// Copyright 2015 Google Inc. All rights reserved
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// +build ignore

#include "ninja.h"

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>

#include <fstream>
#include <map>
#include <ostream>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>

#include "command.h"
#include "dep.h"
#include "eval.h"
#include "file_cache.h"
#include "fileutil.h"
#include "find.h"
#include "flags.h"
#include "func.h"
#include "io.h"
#include "log.h"
#include "stats.h"
#include "string_piece.h"
#include "stringprintf.h"
#include "strutil.h"
#include "timeutil.h"
#include "var.h"
#include "version.h"

static size_t FindCommandLineFlag(StringPiece cmd, StringPiece name) {
  const size_t found = cmd.find(name);
  if (found == std::string::npos || found == 0)
    return std::string::npos;
  return found;
}

static StringPiece FindCommandLineFlagWithArg(StringPiece cmd,
                                              StringPiece name) {
  size_t index = FindCommandLineFlag(cmd, name);
  if (index == std::string::npos)
    return StringPiece();

  StringPiece val = TrimLeftSpace(cmd.substr(index + name.size()));
  index = val.find(name);
  while (index != std::string::npos) {
    val = TrimLeftSpace(val.substr(index + name.size()));
    index = val.find(name);
  }

  index = val.find_first_of(" \t");
  return val.substr(0, index);
}

static bool StripPrefix(StringPiece p, StringPiece* s) {
  if (!HasPrefix(*s, p))
    return false;
  *s = s->substr(p.size());
  return true;
}

size_t GetGomaccPosForAndroidCompileCommand(StringPiece cmdline) {
  size_t index = cmdline.find(' ');
  if (index == std::string::npos)
    return std::string::npos;
  StringPiece cmd = cmdline.substr(0, index);
  if (HasSuffix(cmd, "ccache")) {
    index++;
    size_t pos = GetGomaccPosForAndroidCompileCommand(cmdline.substr(index));
    return pos == std::string::npos ? std::string::npos : pos + index;
  }
  if (!StripPrefix("prebuilts/", &cmd))
    return std::string::npos;
  if (!StripPrefix("gcc/", &cmd) && !StripPrefix("clang/", &cmd))
    return std::string::npos;
  if (!HasSuffix(cmd, "gcc") && !HasSuffix(cmd, "g++") &&
      !HasSuffix(cmd, "clang") && !HasSuffix(cmd, "clang++")) {
    return std::string::npos;
  }

  StringPiece rest = cmdline.substr(index);
  return rest.find(" -c ") != std::string::npos ? 0 : std::string::npos;
}

static bool GetDepfileFromCommandImpl(StringPiece cmd, std::string* out) {
  if ((FindCommandLineFlag(cmd, " -MD") == std::string::npos &&
       FindCommandLineFlag(cmd, " -MMD") == std::string::npos) ||
      FindCommandLineFlag(cmd, " -c") == std::string::npos) {
    return false;
  }

  StringPiece mf = FindCommandLineFlagWithArg(cmd, " -MF");
  if (!mf.empty()) {
    mf.AppendToString(out);
    return true;
  }

  StringPiece o = FindCommandLineFlagWithArg(cmd, " -o");
  if (o.empty()) {
    ERROR("Cannot find the depfile in %s", cmd.as_string().c_str());
    return false;
  }

  StripExt(o).AppendToString(out);
  *out += ".d";
  return true;
}

bool GetDepfileFromCommand(std::string* cmd, std::string* out) {
  CHECK(!cmd->empty());
  if (!GetDepfileFromCommandImpl(*cmd, out))
    return false;

  // A hack for Android - llvm-rs-cc seems not to emit a dep file.
  if (cmd->find("bin/llvm-rs-cc ") != std::string::npos) {
    return false;
  }

  // TODO: A hack for Makefiles generated by automake.

  // A hack for Android to get .P files instead of .d.
  std::string p;
  StripExt(*out).AppendToString(&p);
  p += ".P";
  if (cmd->find(p) != std::string::npos) {
    const std::string rm_f = "; rm -f " + *out;
    const size_t found = cmd->find(rm_f);
    if (found == std::string::npos) {
      ERROR("Cannot find removal of .d file: %s", cmd->c_str());
    }
    cmd->erase(found, rm_f.size());
    return true;
  }

  // A hack for Android. For .s files, GCC does not use C
  // preprocessor, so it ignores -MF flag.
  std::string as = "/";
  StripExt(Basename(*out)).AppendToString(&as);
  as += ".s";
  if (cmd->find(as) != std::string::npos) {
    return false;
  }

  *cmd += "&& cp ";
  *cmd += *out;
  *cmd += ' ';
  *cmd += *out;
  *cmd += ".tmp ";
  *out += ".tmp";
  return true;
}

struct NinjaNode {
  const DepNode* node;
  std::vector<Command> commands;
  int rule_id;
};

class NinjaGenerator {
 public:
  NinjaGenerator(Evaluator* ev, double start_time)
      : ce_(ev),
        ev_(ev),
        rule_id_(0),
        shell_(EscapeNinja(ev->GetShell())),
        shell_flags_(EscapeNinja(ev->GetShellFlag())),
        kati_binary_(GetExecutablePath()),
        start_time_(start_time),
        default_target_(NULL) {
    ev_->set_avoid_io(true);
    const std::string use_goma_str = ev->EvalVar(Intern("USE_GOMA"));
    use_goma_ = !(use_goma_str.empty() || use_goma_str == "false");
    if (g_flags.goma_dir)
      gomacc_ = StringPrintf("%s/gomacc ", g_flags.goma_dir);
  }

  ~NinjaGenerator() { ev_->set_avoid_io(false); }

  void Generate(const std::vector<NamedDepNode>& nodes,
                const std::string& orig_args) {
    unlink(GetNinjaStampFilename().c_str());
    PopulateNinjaNodes(nodes);
    GenerateNinja();
    GenerateShell();
    GenerateStamp(orig_args);
  }

  static std::string GetStampTempFilename() {
    return GetFilename(".kati_stamp%s.tmp");
  }

  static std::string GetFilename(const char* fmt) {
    std::string r = g_flags.ninja_dir ? g_flags.ninja_dir : ".";
    r += '/';
    r += StringPrintf(fmt, g_flags.ninja_suffix ? g_flags.ninja_suffix : "");
    return r;
  }

 private:
  void PopulateNinjaNodes(const std::vector<NamedDepNode>& nodes) {
    ScopedTimeReporter tr("ninja gen (eval)");
    for (auto const& [symbol, depnode] : nodes) {
      PopulateNinjaNode(*depnode);
    }
  }

  void PopulateNinjaNode(const DepNode& node) {
    if (done_.exists(node.output)) {
      return;
    }
    done_.insert(node.output);
    ScopedFrame frame(
        ce_.evaluator()->Enter(FrameType::NINJA, node.output.str(), node.loc));

    // A hack to exclude out phony target in Android. If this exists,
    // "ninja -t clean" tries to remove this directory and fails.
    if (g_flags.detect_android_echo && node.output.str() == "out")
      return;

    // This node is a leaf node
    if (!node.has_rule && !node.is_phony) {
      return;
    }

    NinjaNode& nn = nodes_.emplace_back();
    nn.node = &node;
    nn.commands = ce_.Eval(node);
    nn.rule_id = nn.commands.empty() ? -1 : rule_id_++;

    for (auto const& [symbol, depnode] : node.deps) {
      PopulateNinjaNode(*depnode);
    }
    for (auto const& [symbol, depnode] : node.order_onlys) {
      PopulateNinjaNode(*depnode);
    }
    for (auto const& [symbol, depnode] : node.validations) {
      PopulateNinjaNode(*depnode);
    }
  }

  StringPiece TranslateCommand(const char* in, std::string* cmd_buf) {
    const size_t orig_size = cmd_buf->size();
    bool prev_backslash = false;
    // Set space as an initial value so the leading comment will be
    // stripped out.
    char prev_char = ' ';
    char quote = 0;
    for (; *in; in++) {
      switch (*in) {
        case '#':
          if (quote == 0 && isspace(prev_char)) {
            while (in[1] && *in != '\n')
              in++;
          } else {
            *cmd_buf += *in;
          }
          break;

        case '\'':
        case '"':
        case '`':
          if (quote) {
            if (quote == *in)
              quote = 0;
          } else if (!prev_backslash) {
            quote = *in;
          }
          *cmd_buf += *in;
          break;

        case '$':
          *cmd_buf += "$$";
          break;

        case '\n':
          if (prev_backslash) {
            cmd_buf->resize(cmd_buf->size() - 1);
          } else {
            *cmd_buf += ' ';
          }
          break;

        case '\\':
          *cmd_buf += '\\';
          break;

        default:
          *cmd_buf += *in;
      }

      if (*in == '\\') {
        prev_backslash = !prev_backslash;
      } else {
        prev_backslash = false;
      }

      prev_char = *in;
    }

    if (prev_backslash) {
      cmd_buf->resize(cmd_buf->size() - 1);
    }

    while (true) {
      char c = (*cmd_buf)[cmd_buf->size() - 1];
      if (!isspace(c) && c != ';')
        break;
      cmd_buf->resize(cmd_buf->size() - 1);
    }

    return StringPiece(cmd_buf->data() + orig_size,
                       cmd_buf->size() - orig_size);
  }

  bool IsOutputMkdir(const char* name, StringPiece cmd) {
    if (!HasPrefix(cmd, "mkdir -p ")) {
      return false;
    }
    cmd = cmd.substr(9, cmd.size());
    if (cmd.get(cmd.size() - 1) == '/') {
      cmd = cmd.substr(0, cmd.size() - 1);
    }

    StringPiece dir = Dirname(name);
    if (cmd == dir) {
      return true;
    }
    return false;
  }

  bool GetDescriptionFromCommand(StringPiece cmd, std::string* out) {
    if (!HasPrefix(cmd, "echo ")) {
      return false;
    }
    cmd = cmd.substr(5, cmd.size());

    bool prev_backslash = false;
    char quote = 0;
    std::string out_buf;

    // Strip outer quotes, and fail if it is not a single echo command
    for (StringPiece::iterator in = cmd.begin(); in != cmd.end(); in++) {
      if (prev_backslash) {
        prev_backslash = false;
        out_buf += *in;
      } else if (*in == '\\') {
        prev_backslash = true;
        out_buf += *in;
      } else if (quote) {
        if (*in == quote) {
          quote = 0;
        } else {
          out_buf += *in;
        }
      } else {
        switch (*in) {
          case '\'':
          case '"':
          case '`':
            quote = *in;
            break;

          case '<':
          case '>':
          case '&':
          case '|':
          case ';':
            return false;

          default:
            out_buf += *in;
        }
      }
    }

    *out = out_buf;
    return true;
  }

  bool GenShellScript(const char* name,
                      const std::vector<Command>& commands,
                      std::string* cmd_buf,
                      std::string* description) {
    bool got_descritpion = false;
    bool use_gomacc = false;
    auto command_count = commands.size();
    for (const Command& c : commands) {
      size_t cmd_begin = cmd_buf->size();

      if (!cmd_buf->empty()) {
        *cmd_buf += " && ";
      }

      const char* in = c.cmd.c_str();
      while (isspace(*in))
        in++;

      bool needs_subshell = (command_count > 1 || c.ignore_error);

      if (needs_subshell)
        *cmd_buf += '(';

      size_t cmd_start = cmd_buf->size();
      StringPiece translated = TranslateCommand(in, cmd_buf);
      if (g_flags.detect_android_echo && !got_descritpion && !c.echo &&
          GetDescriptionFromCommand(translated, description)) {
        got_descritpion = true;
        translated.clear();
      } else if (IsOutputMkdir(name, translated) && !c.echo && cmd_begin == 0) {
        translated.clear();
      }
      if (translated.empty()) {
        cmd_buf->resize(cmd_begin);
        command_count -= 1;
        continue;
      } else if (g_flags.goma_dir) {
        size_t pos = GetGomaccPosForAndroidCompileCommand(translated);
        if (pos != std::string::npos) {
          cmd_buf->insert(cmd_start + pos, gomacc_);
          use_gomacc = true;
        }
      } else if (translated.find("/gomacc") != std::string::npos) {
        use_gomacc = true;
      }

      if (c.ignore_error) {
        *cmd_buf += " ; true";
      }

      if (needs_subshell)
        *cmd_buf += " )";
    }
    return (use_goma_ || g_flags.remote_num_jobs || g_flags.goma_dir) &&
           !use_gomacc;
  }

  bool GetDepfile(const DepNode* node,
                  std::string* cmd_buf,
                  std::string* depfile) {
    if (node->depfile_var) {
      node->depfile_var->Eval(ev_, depfile);
      return true;
    }
    if (!g_flags.detect_depfiles)
      return false;

    *cmd_buf += ' ';
    bool result = GetDepfileFromCommand(cmd_buf, depfile);
    cmd_buf->resize(cmd_buf->size() - 1);
    return result;
  }

  void EmitDepfile(const NinjaNode& nn,
                   std::string* cmd_buf,
                   std::ostream& out) {
    const DepNode* node = nn.node;
    std::string depfile;
    if (!GetDepfile(node, cmd_buf, &depfile))
      return;
    out << " depfile = " << depfile << "\n";
    out << " deps = gcc\n";
  }

  void EmitNode(const NinjaNode& nn, std::ostream& out) {
    const DepNode* node = nn.node;
    const std::vector<Command>& commands = nn.commands;

    std::string rule_name = "phony";
    bool use_local_pool = false;
    if (IsSpecialTarget(node->output)) {
      return;
    }
    if (g_flags.enable_debug) {
      out << "# " << (node->loc.filename ? node->loc.filename : "(null)") << ':'
          << node->loc.lineno << "\n";
    }
    if (!commands.empty()) {
      rule_name = StringPrintf("rule%d", nn.rule_id);
      out << "rule " << rule_name << "\n";

      std::string description = "build $out";
      std::string cmd_buf;
      use_local_pool |= GenShellScript(node->output.c_str(), commands, &cmd_buf,
                                       &description);
      out << " description = " << description << "\n";
      EmitDepfile(nn, &cmd_buf, out);

      // It seems Linux is OK with ~130kB and Mac's limit is ~250kB.
      // TODO: Find this number automatically.
      if (cmd_buf.size() > 100 * 1000) {
        out << " rspfile = $out.rsp\n";
        out << " rspfile_content = " << cmd_buf << "\n";
        out << " command = " << shell_ << " $out.rsp\n";
      } else {
        EscapeShell(&cmd_buf);
        out << " command = " << shell_ << ' ' << shell_flags_ << " \""
            << cmd_buf << "\"\n";
      }
      if (node->is_restat) {
        out << " restat = 1\n";
      }
    }

    EmitBuild(nn, rule_name, use_local_pool, out);
  }

  std::string EscapeNinja(const std::string& s) const {
    if (s.find_first_of("$: ") == std::string::npos)
      return s;
    std::string r;
    for (char c : s) {
      switch (c) {
        case '$':
        case ':':
        case ' ':
          r += '$';
          [[fallthrough]];
        default:
          r += c;
      }
    }
    return r;
  }

  std::string EscapeBuildTarget(Symbol s) const { return EscapeNinja(s.str()); }

  void EmitBuild(const NinjaNode& nn,
                 const std::string& rule_name,
                 bool use_local_pool,
                 std::ostream& out) {
    const DepNode* node = nn.node;
    std::string target = EscapeBuildTarget(node->output);
    out << "build " << target;
    if (!node->implicit_outputs.empty()) {
      out << " |";
      for (Symbol output : node->implicit_outputs) {
        out << " " << EscapeBuildTarget(output);
      }
    }
    out << ": " << rule_name;
    std::vector<Symbol> order_onlys;
    if (node->is_phony && !g_flags.use_ninja_phony_output) {
      out << " _kati_always_build_";
    }
    for (auto const& d : node->deps) {
      out << " " << EscapeBuildTarget(d.first).c_str();
    }
    if (!node->order_onlys.empty()) {
      out << " ||";
      for (auto const& d : node->order_onlys) {
        out << " " << EscapeBuildTarget(d.first).c_str();
      }
    }
    if (!node->validations.empty()) {
      out << " |@";
      for (auto const& d : node->validations) {
        out << " " << EscapeBuildTarget(d.first).c_str();
      }
    }

    out << "\n";

    if (!node->symlink_outputs.empty()) {
      out << " symlink_outputs =";
      for (auto const& s : node->symlink_outputs) {
        out << " " << EscapeBuildTarget(s);
      }
      out << "\n";
    }

    std::string pool;
    if (node->ninja_pool_var) {
      node->ninja_pool_var->Eval(ev_, &pool);
    }

    if (pool != "") {
      if (pool != "none") {
        out << " pool = " << pool << "\n";
      }
    } else if (g_flags.default_pool && rule_name != "phony") {
      out << " pool = " << g_flags.default_pool << "\n";
    } else if (use_local_pool) {
      out << " pool = local_pool\n";
    }
    if (node->is_phony && g_flags.use_ninja_phony_output) {
      out << " phony_output = true\n";
    }
    if (node->is_default_target) {
      std::unique_lock<std::mutex> lock(mu_);
      default_target_ = node;
    }
  }

  static std::string GetEnvScriptFilename() { return GetFilename("env%s.sh"); }

  void GenerateNinja() {
    ScopedTimeReporter tr("ninja gen (emit)");
    std::ofstream out(GetNinjaFilename(), std::ios::binary);
    if (!out)
      PERROR("fopen(build.ninja) failed");

    out << "# Generated by kati " << kGitVersion << "\n\n";

    if (!used_envs_.empty()) {
      out << "# Environment variables used:\n";
      for (const auto& [key, value] : used_envs_) {
        out << "# " << key << "=" << value << '\n';
      }
      out << '\n';
    }

    if (!g_flags.no_ninja_prelude) {
      if (g_flags.ninja_dir) {
        out << "builddir = " << g_flags.ninja_dir << "\n\n";
      }

      out << "pool local_pool\n"
          << " depth = " << g_flags.num_jobs << "\n\n";

      if (!g_flags.use_ninja_phony_output) {
        out << "build _kati_always_build_: phony\n\n";
      }
    }

    if (!g_flags.generate_empty_ninja) {
      for (const auto& node : nodes_) {
        EmitNode(node, out);
      }

      std::string default_targets;
      if (g_flags.targets.empty() || g_flags.gen_all_targets) {
        CHECK(default_target_);
        default_targets = EscapeBuildTarget(default_target_->output);
      } else {
        for (Symbol s : g_flags.targets) {
          if (!default_targets.empty())
            default_targets += ' ';
          default_targets += EscapeBuildTarget(s);
        }
      }
      out << "\n"
          << "default " << default_targets << '\n';
    }

    SymbolSet used_env_vars(Vars::used_env_vars());
    // PATH changes $(shell).
    used_env_vars.insert(Intern("PATH"));
    for (Symbol e : used_env_vars) {
      StringPiece val(getenv(e.c_str()));
      used_envs_.emplace(e.str(), val.as_string());
    }
  }

  void GenerateShell() {
    FILE* fp = fopen(GetEnvScriptFilename().c_str(), "wb");
    if (fp == NULL)
      PERROR("fopen(env.sh) failed");

    fprintf(fp, "#!/bin/sh\n");
    fprintf(fp, "# Generated by kati %s\n", kGitVersion);
    fprintf(fp, "\n");

    for (const auto& [symbol, is_exported] : ev_->exports()) {
      if (is_exported) {
        const std::string val = ev_->EvalVar(symbol);
        fprintf(fp, "export '%s'='%s'\n", symbol.c_str(), val.c_str());
      } else {
        fprintf(fp, "unset '%s'\n", symbol.c_str());
      }
    }

    fclose(fp);

    fp = fopen(GetNinjaShellScriptFilename().c_str(), "wb");
    if (fp == NULL)
      PERROR("fopen(ninja.sh) failed");

    fprintf(fp, "#!/bin/sh\n");
    fprintf(fp, "# Generated by kati %s\n", kGitVersion);
    fprintf(fp, "\n");

    fprintf(fp, ". %s\n", GetEnvScriptFilename().c_str());

    fprintf(fp, "exec ninja -f %s ", GetNinjaFilename().c_str());
    if (g_flags.remote_num_jobs > 0) {
      fprintf(fp, "-j%d ", g_flags.remote_num_jobs);
    } else if (g_flags.goma_dir) {
      fprintf(fp, "-j500 ");
    }
    fprintf(fp, "\"$@\"\n");

    fclose(fp);

    if (chmod(GetNinjaShellScriptFilename().c_str(), 0755) != 0)
      PERROR("chmod ninja.sh failed");
  }

  void GenerateStamp(const std::string& orig_args) {
    FILE* fp = fopen(GetStampTempFilename().c_str(), "wb");
    CHECK(fp);

    size_t r = fwrite(&start_time_, sizeof(start_time_), 1, fp);
    CHECK(r == 1);

    std::unordered_set<std::string> makefiles;
    MakefileCacheManager::Get().GetAllFilenames(&makefiles);
    DumpInt(fp, makefiles.size() + 1);
    DumpString(fp, kati_binary_);
    for (const std::string& makefile : makefiles) {
      DumpString(fp, makefile);
    }

    DumpInt(fp, Evaluator::used_undefined_vars().size());
    for (Symbol v : Evaluator::used_undefined_vars()) {
      DumpString(fp, v.str());
    }
    DumpInt(fp, used_envs_.size());
    for (const auto& [key, value] : used_envs_) {
      DumpString(fp, key);
      DumpString(fp, value);
    }

    auto& globs = GetAllGlobCache();
    DumpInt(fp, globs.size());
    for (const auto& [key, files] : globs) {
      DumpString(fp, key);
#if 0
      std::unordered_set<std::string> dirs;
      GetReadDirs(p.first, files, &dirs);
      DumpInt(fp, dirs.size());
      for (const std::string& dir : dirs) {
        DumpString(fp, dir);
      }
#endif
      DumpInt(fp, files.size());
      for (const std::string& file : files) {
        DumpString(fp, file);
      }
    }

    const std::vector<CommandResult*>& crs = GetShellCommandResults();
    DumpInt(fp, crs.size());
    for (CommandResult* cr : crs) {
      DumpInt(fp, static_cast<int>(cr->op));
      DumpString(fp, cr->shell);
      DumpString(fp, cr->shellflag);
      DumpString(fp, cr->cmd);
      DumpString(fp, cr->result);
      DumpString(fp, cr->loc.filename);
      DumpInt(fp, cr->loc.lineno);

      if (cr->op == CommandOp::FIND) {
        std::vector<std::string> missing_dirs;
        for (StringPiece fd : cr->find->finddirs) {
          const std::string& d = ConcatDir(cr->find->chdir, fd);
          if (!Exists(d))
            missing_dirs.push_back(d);
        }
        DumpInt(fp, missing_dirs.size());
        for (const std::string& d : missing_dirs) {
          DumpString(fp, d);
        }

        DumpInt(fp, cr->find->found_files->size());
        for (StringPiece s : *cr->find->found_files) {
          DumpString(fp, ConcatDir(cr->find->chdir, s));
        }

        DumpInt(fp, cr->find->read_dirs->size());
        for (StringPiece s : *cr->find->read_dirs) {
          DumpString(fp, ConcatDir(cr->find->chdir, s));
        }
      }
    }

    DumpString(fp, orig_args);

    fclose(fp);

    rename(GetStampTempFilename().c_str(), GetNinjaStampFilename().c_str());
  }

  CommandEvaluator ce_;
  Evaluator* ev_;
  SymbolSet done_;
  int rule_id_;
  bool use_goma_;
  std::string gomacc_;
  const std::string shell_;
  const std::string shell_flags_;
  std::map<std::string, std::string> used_envs_;
  const std::string kati_binary_;
  const double start_time_;
  std::vector<NinjaNode> nodes_;

  std::mutex mu_;
  const DepNode* default_target_;
};

string GetNinjaFilename() {
  return NinjaGenerator::GetFilename("build%s.ninja");
}

string GetNinjaShellScriptFilename() {
  return NinjaGenerator::GetFilename("ninja%s.sh");
}

string GetNinjaStampFilename() {
  return NinjaGenerator::GetFilename(".kati_stamp%s");
}

void GenerateNinja(const std::vector<NamedDepNode>& nodes,
                   Evaluator* ev,
                   const std::string& orig_args,
                   double start_time) {
  NinjaGenerator ng(ev, start_time);
  ng.Generate(nodes, orig_args);
}
