//===- FuzzerFork.cpp - run fuzzing in separate subprocesses --------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Spawn and orchestrate separate fuzzing processes.
//===----------------------------------------------------------------------===//

#include "FuzzerCommand.h"
#include "FuzzerFork.h"
#include "FuzzerIO.h"
#include "FuzzerMerge.h"
#include "FuzzerSHA1.h"
#include "FuzzerUtil.h"

namespace fuzzer {

struct FuzzJob {
  // Inputs.
  Command Cmd;
  Vector<std::string> Files;
  std::string CorpusDir;
  std::string LogPath;
  std::string CFPath;
  int MaxTotalTimeSec;

  // Fuzzing Outputs.
  int ExitCode;
};

struct GlobalEnv {
  const Vector<std::string> *Args;
  std::string MainCorpusDir;
  Set<uint32_t> Features;
  Vector<std::string> Files;
};

void RunOneFuzzingJob(FuzzJob *Job) {
  Command &Cmd = Job->Cmd;
  if (!Job->Files.empty()) {
    std::string Seeds;
    for (const auto &File : Job->Files)
        Seeds += (Seeds.empty() ? "" : ",") + File;
    Cmd.addFlag("seed_inputs", Seeds);
  }
  Cmd.addFlag("max_total_time", std::to_string(Job->MaxTotalTimeSec));
  Cmd.setOutputFile(Job->LogPath);
  Cmd.combineOutAndErr();
  Cmd.addArgument(Job->CorpusDir);
  RmDirRecursive(Job->CorpusDir);
  MkDir(Job->CorpusDir);
  Job->ExitCode = ExecuteCommand(Cmd);
}

void RunOneMergeJob(GlobalEnv *Env, FuzzJob *Job) {
  Vector<SizedFile> TempFiles;
  GetSizedFilesFromDir(Job->CorpusDir, &TempFiles);

  Vector<std::string>FilesToAdd;
  Set<uint32_t> NewFeatures;
  CrashResistantMerge(*Env->Args, {}, TempFiles, &FilesToAdd, Env->Features,
                      &NewFeatures, Job->CFPath, false);
  RemoveFile(Job->CFPath);
  for (auto &Path : FilesToAdd) {
    auto U = FileToVector(Path);
    auto NewPath = DirPlusFile(Env->MainCorpusDir, Hash(U));
    WriteToFile(U, NewPath);
    Env->Files.push_back(NewPath);
  }
  RmDirRecursive(Job->CorpusDir);
  Env->Features.insert(NewFeatures.begin(), NewFeatures.end());
  Printf("INFO: temp_files: %zd files_added: %zd newft: %zd ft: %zd\n",
         TempFiles.size(), FilesToAdd.size(), NewFeatures.size(),
         Env->Features.size());
}

// This is just a skeleton of an experimental -fork=1 feature.
void FuzzWithFork(Random &Rand, const FuzzingOptions &Options,
                  const Vector<std::string> &Args,
                  const Vector<std::string> &CorpusDirs) {
  Printf("INFO: -fork=1: doing fuzzing in a separate process in order to "
         "be more resistant to crashes, timeouts, and OOMs\n");

  GlobalEnv Env;
  Env.Args = &Args;

  Vector<SizedFile> SeedFiles;
  for (auto &Dir : CorpusDirs)
    GetSizedFilesFromDir(Dir, &SeedFiles);
  std::sort(SeedFiles.begin(), SeedFiles.end());
  auto TempDir = TempPath(".dir");
  RmDirRecursive(TempDir);  // just in case there is a leftover from an old run.
  MkDir(TempDir);

  auto CFPath = DirPlusFile(TempDir, "merge.txt");
  auto LogPath = DirPlusFile(TempDir, "sub.log");

  if (CorpusDirs.empty())
    MkDir(Env.MainCorpusDir = DirPlusFile(TempDir, "C"));
  else
    Env.MainCorpusDir = CorpusDirs[0];

  auto TempCorpusDir = DirPlusFile(TempDir, "C0");

  CrashResistantMerge(*Env.Args, {}, SeedFiles, &Env.Files, {}, &Env.Features,
                      CFPath, false);
  RemoveFile(CFPath);
  Printf("INFO: -fork=1: %zd seeds, starting to fuzz; scratch: %s\n",
         Env.Files.size(), TempDir.c_str());

  Command BaseCmd(*Env.Args);
  BaseCmd.removeFlag("fork");
  for (auto &C : CorpusDirs) // Remove all corpora from the args.
    BaseCmd.removeArgument(C);
  BaseCmd.addFlag("reload", "0");  // working in an isolated dir, no reload.
  int ExitCode = 0;


  for (size_t i = 1; i < 1000000; i++) {
    // TODO: take new files from disk e.g. those generated by another process.

    FuzzJob Job;
    Job.Cmd = BaseCmd;
    if (size_t CorpusSubsetSize = std::min(Env.Files.size(), (size_t)100))
      for (size_t i = 0; i < CorpusSubsetSize; i++)
        Job.Files.push_back(Env.Files[Rand.SkewTowardsLast(Env.Files.size())]);
    Job.CorpusDir = TempCorpusDir;
    Job.LogPath = LogPath;
    Job.CFPath = CFPath;
    // Start from very short runs and gradually increase them.
    Job.MaxTotalTimeSec = std::min(300, (int)i);
    RunOneFuzzingJob(&Job);

    if (Options.Verbosity >= 2)
      Printf("done [%d] %s\n", Job.ExitCode, Job.Cmd.toString().c_str());
    if (Job.ExitCode == Options.InterruptExitCode)
      break;

    RunOneMergeJob(&Env, &Job);

    // Continue if our crash is one of the ignorred ones.
    if (Options.IgnoreTimeouts && Job.ExitCode == Options.TimeoutExitCode)
      continue;
    if (Options.IgnoreOOMs && Job.ExitCode == Options.OOMExitCode)
      continue;
    // And exit if we don't ignore this crash.
    if (Job.ExitCode != 0) {
      Printf("INFO: log from the inner process:\n%s",
             FileToString(LogPath).c_str());
      ExitCode = Job.ExitCode;
      break;
    }
  }

  RmDirRecursive(TempDir);

  // Use the exit code from the last child process.
  Printf("Fork: exiting: %d\n", ExitCode);
  exit(ExitCode);
}

} // namespace fuzzer

