// 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 <algorithm>
#include <map>
#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 "var.h"
#include "version.h"

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

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

  StringPiece val = TrimLeftSpace(cmd.substr(index + name.size()));
  index = val.find(name);
  while (index != 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 == string::npos)
    return string::npos;
  StringPiece cmd = cmdline.substr(0, index);
  if (HasSuffix(cmd, "ccache")) {
    index++;
    size_t pos = GetGomaccPosForAndroidCompileCommand(cmdline.substr(index));
    return pos == string::npos ? string::npos : pos + index;
  }
  if (!StripPrefix("prebuilts/", &cmd))
    return string::npos;
  if (!StripPrefix("gcc/", &cmd) && !StripPrefix("clang/", &cmd))
    return string::npos;
  if (!HasSuffix(cmd, "gcc") && !HasSuffix(cmd, "g++") &&
      !HasSuffix(cmd, "clang") && !HasSuffix(cmd, "clang++")) {
    return string::npos;
  }

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

static bool GetDepfileFromCommandImpl(StringPiece cmd, string* out) {
  if ((FindCommandLineFlag(cmd, " -MD") == string::npos &&
       FindCommandLineFlag(cmd, " -MMD") == string::npos) ||
      FindCommandLineFlag(cmd, " -c") == 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(string* cmd, 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 ") != string::npos) {
    return false;
  }

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

  // A hack for Android to get .P files instead of .d.
  string p;
  StripExt(*out).AppendToString(&p);
  p += ".P";
  if (cmd->find(p) != string::npos) {
    const string rm_f = "; rm -f " + *out;
    const size_t found = cmd->find(rm_f);
    if (found == 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.
  string as = "/";
  StripExt(Basename(*out)).AppendToString(&as);
  as += ".s";
  if (cmd->find(as) != string::npos) {
    return false;
  }

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

class NinjaGenerator {
 public:
  NinjaGenerator(const char* ninja_suffix, const char* ninja_dir, Evaluator* ev,
                 double start_time)
      : ce_(ev), ev_(ev), fp_(NULL), rule_id_(0), start_time_(start_time) {
    ev_->set_avoid_io(true);
    shell_ = ev->EvalVar(kShellSym);
    if (g_flags.goma_dir)
      gomacc_ = StringPrintf("%s/gomacc ", g_flags.goma_dir);
    if (ninja_suffix) {
      ninja_suffix_ = ninja_suffix;
    }
    if (ninja_dir) {
      ninja_dir_ = ninja_dir;
    } else {
      ninja_dir_ = ".";
    }

    GetExecutablePath(&kati_binary_);
  }

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

  void Generate(const vector<DepNode*>& nodes,
                bool build_all_targets,
                const string& orig_args) {
    GenerateNinja(nodes, build_all_targets, orig_args);
    GenerateShell();
    GenerateStamp(orig_args);
  }

  static string GetStampFilename(const char* ninja_dir,
                                 const char* ninja_suffix) {
    return StringPrintf("%s/.kati_stamp%s",
                        ninja_dir ? ninja_dir : ".",
                        ninja_suffix ? ninja_suffix : "");
  }

 private:
  string GenRuleName() {
    return StringPrintf("rule%d", rule_id_++);
  }

  StringPiece TranslateCommand(const char* in, 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 GetDescriptionFromCommand(StringPiece cmd, string *out) {
    if (!HasPrefix(cmd, "echo ")) {
      return false;
    }
    cmd = cmd.substr(5, cmd.size());

    bool prev_backslash = false;
    char quote = 0;
    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 vector<Command*>& commands,
                      string* cmd_buf,
                      string* description) {
    bool got_descritpion = false;
    bool use_gomacc = false;
    bool should_ignore_error = false;
    for (const Command* c : commands) {
      if (!cmd_buf->empty()) {
        if (should_ignore_error) {
          *cmd_buf += " ; ";
        } else {
          *cmd_buf += " && ";
        }
      }
      should_ignore_error = c->ignore_error;

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

      bool needs_subshell = commands.size() > 1;
      if (*in == '(') {
        needs_subshell = false;
      }

      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;
        cmd_buf->resize(cmd_start);
        translated.clear();
      }
      if (translated.empty()) {
        *cmd_buf += "true";
      } else if (g_flags.goma_dir) {
        size_t pos = GetGomaccPosForAndroidCompileCommand(translated);
        if (pos != string::npos) {
          cmd_buf->insert(cmd_start + pos, gomacc_);
          use_gomacc = true;
        }
      } else if (translated.find("/gomacc") != string::npos) {
        use_gomacc = true;
      }

      if (c == commands.back() && c->ignore_error) {
        *cmd_buf += " ; true";
      }

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

  void EmitDepfile(string* cmd_buf) {
    *cmd_buf += ' ';
    string depfile;
    bool result = GetDepfileFromCommand(cmd_buf, &depfile);
    cmd_buf->resize(cmd_buf->size()-1);
    if (!result)
      return;
    fprintf(fp_, " depfile = %s\n", depfile.c_str());
    fprintf(fp_, " deps = gcc\n");
  }

  void EmitNode(DepNode* node) {
    auto p = done_.insert(node->output);
    if (!p.second)
      return;

    // 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;
    }

    vector<Command*> commands;
    ce_.Eval(node, &commands);

    string rule_name = "phony";
    bool use_local_pool = false;
    if (!commands.empty()) {
      rule_name = GenRuleName();
      fprintf(fp_, "rule %s\n", rule_name.c_str());

      string description = "build $out";
      string cmd_buf;
      use_local_pool |= GenShellScript(commands, &cmd_buf, &description);
      fprintf(fp_, " description = %s\n", description.c_str());
      EmitDepfile(&cmd_buf);

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

    EmitBuild(node, rule_name);
    if (use_local_pool)
      fprintf(fp_, " pool = local_pool\n");

    for (DepNode* d : node->deps) {
      EmitNode(d);
    }
    for (DepNode* d : node->order_onlys) {
      EmitNode(d);
    }
  }

  string EscapeBuildTarget(Symbol s) const {
    if (s.str().find_first_of("$: ") == string::npos)
      return s.str();
    string r;
    for (char c : s.str()) {
      switch (c) {
        case '$':
        case ':':
        case ' ':
          r += '$';
          // fall through.
        default:
          r += c;
      }
    }
    return r;
  }

  void EscapeShell(string* s) const {
    if (s->find_first_of("$`!\\\"") == string::npos)
      return;
    string r;
    bool last_dollar = false;
    for (char c : *s) {
      switch (c) {
        case '$':
          if (last_dollar) {
            r += c;
            last_dollar = false;
          } else {
            r += '\\';
            r += c;
            last_dollar = true;
          }
          break;
        case '`':
        case '"':
        case '!':
        case '\\':
          r += '\\';
          // fall through.
        default:
          r += c;
          last_dollar = false;
      }
    }
    s->swap(r);
  }

  void EmitBuild(DepNode* node, const string& rule_name) {
    fprintf(fp_, "build %s: %s",
            EscapeBuildTarget(node->output).c_str(),
            rule_name.c_str());
    vector<Symbol> order_onlys;
    if (node->is_phony) {
      fprintf(fp_, " _kati_always_build_");
    }
    for (DepNode* d : node->deps) {
      fprintf(fp_, " %s", EscapeBuildTarget(d->output).c_str());
    }
    if (!node->order_onlys.empty()) {
      fprintf(fp_, " ||");
      for (DepNode* d : node->order_onlys) {
        fprintf(fp_, " %s", EscapeBuildTarget(d->output).c_str());
      }
    }
    fprintf(fp_, "\n");
  }

  void EmitRegenRules(const string& orig_args) {
    if (!g_flags.gen_regen_rule)
      return;

    fprintf(fp_, "rule regen_ninja\n");
    fprintf(fp_, " command = %s\n", orig_args.c_str());
    fprintf(fp_, " generator = 1\n");
    fprintf(fp_, " description = Regenerate ninja files due to dependency\n");
    fprintf(fp_, "build %s: regen_ninja", GetNinjaFilename().c_str());
    unordered_set<string> makefiles;
    MakefileCacheManager::Get()->GetAllFilenames(&makefiles);
    for (const string& makefile : makefiles) {
      fprintf(fp_, " %.*s", SPF(makefile));
    }
    fprintf(fp_, " %s", kati_binary_.c_str());
    fprintf(fp_, "\n\n");
  }

  string GetNinjaFilename() const {
    return StringPrintf("%s/build%s.ninja",
                        ninja_dir_.c_str(), ninja_suffix_.c_str());
  }

  string GetShellScriptFilename() const {
    return StringPrintf("%s/ninja%s.sh",
                        ninja_dir_.c_str(), ninja_suffix_.c_str());
  }

  string GetStampFilename() const {
    return GetStampFilename(ninja_dir_.c_str(), ninja_suffix_.c_str());
  }

  void GenerateNinja(const vector<DepNode*>& nodes,
                     bool build_all_targets,
                     const string& orig_args) {
    fp_ = fopen(GetNinjaFilename().c_str(), "wb");
    if (fp_ == NULL)
      PERROR("fopen(build.ninja) failed");

    fprintf(fp_, "# Generated by kati %s\n", kGitVersion);
    fprintf(fp_, "\n");

    if (!used_envs_.empty()) {
      fprintf(fp_, "# Environment variables used:\n");
      for (const auto& p : used_envs_) {
        fprintf(fp_, "# %s=%s\n", p.first.c_str(), p.second.c_str());
      }
      fprintf(fp_, "\n");
    }

    if (ninja_dir_ != ".") {
      fprintf(fp_, "builddir = %s\n\n", ninja_dir_.c_str());
    }

    fprintf(fp_, "pool local_pool\n");
    fprintf(fp_, " depth = %d\n\n", g_flags.num_jobs);

    fprintf(fp_, "build _kati_always_build_: phony\n\n");

    EmitRegenRules(orig_args);

    for (DepNode* node : nodes) {
      EmitNode(node);
    }

    for (Symbol e : Vars::used_env_vars()) {
      StringPiece val(getenv(e.c_str()));
      used_envs_.emplace(e.str(), val.as_string());
    }

    if (!build_all_targets) {
      CHECK(!nodes.empty());
      fprintf(fp_, "\ndefault %s\n",
              EscapeBuildTarget(nodes.front()->output).c_str());
    }

    fclose(fp_);
  }

  void GenerateShell() {
    FILE* fp = fopen(GetShellScriptFilename().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");
    if (ninja_dir_ == ".")
      fprintf(fp, "cd $(dirname \"$0\")\n");

    for (const auto& p : ev_->exports()) {
      if (p.second) {
        const string val = ev_->EvalVar(p.first);
        fprintf(fp, "export '%s'='%s'\n", p.first.c_str(), val.c_str());
      } else {
        fprintf(fp, "unset '%s'\n", p.first.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");

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

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

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

    unordered_set<string> makefiles;
    MakefileCacheManager::Get()->GetAllFilenames(&makefiles);
    DumpInt(fp, makefiles.size() + 1);
    DumpString(fp, kati_binary_);
    for (const 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& p : used_envs_) {
      DumpString(fp, p.first);
      DumpString(fp, p.second);
    }

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

    const vector<CommandResult*>& crs = GetShellCommandResults();
    DumpInt(fp, crs.size());
    for (CommandResult* cr : crs) {
      DumpString(fp, cr->cmd);
      DumpString(fp, cr->result);
      if (!cr->find.get()) {
        // Always re-run this command.
        DumpInt(fp, 0);
        continue;
      }

      DumpInt(fp, 1);

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

      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);
  }

  CommandEvaluator ce_;
  Evaluator* ev_;
  FILE* fp_;
  unordered_set<Symbol> done_;
  int rule_id_;
  string gomacc_;
  string ninja_suffix_;
  string ninja_dir_;
  string shell_;
  map<string, string> used_envs_;
  string kati_binary_;
  double start_time_;
};

void GenerateNinja(const char* ninja_suffix,
                   const char* ninja_dir,
                   const vector<DepNode*>& nodes,
                   Evaluator* ev,
                   bool build_all_targets,
                   const string& orig_args,
                   double start_time) {
  NinjaGenerator ng(ninja_suffix, ninja_dir, ev, start_time);
  ng.Generate(nodes, build_all_targets, orig_args);
}

static bool ShouldIgnoreDirty(StringPiece s) {
  return (g_flags.ignore_dirty_pattern &&
          Pattern(g_flags.ignore_dirty_pattern).Match(s));
}

bool NeedsRegen(const char* ninja_suffix,
                const char* ninja_dir,
                bool ignore_kati_binary,
                bool dump_kati_stamp,
                double start_time,
                const string& orig_args) {
  bool retval = false;
#define RETURN_TRUE do {                         \
    if (dump_kati_stamp)                         \
      retval = true;                             \
    else                                         \
      return true;                               \
  } while (0)

#define LOAD_INT(fp) ({                                                 \
      int v = LoadInt(fp);                                              \
      if (v < 0) {                                                      \
        fprintf(stderr, "incomplete kati_stamp, regenerating...\n");    \
        RETURN_TRUE;                                                    \
      }                                                                 \
      v;                                                                \
    })

#define LOAD_STRING(fp, s) ({                                           \
      if (!LoadString(fp, s)) {                                         \
        fprintf(stderr, "incomplete kati_stamp, regenerating...\n");    \
        RETURN_TRUE;                                                    \
      }                                                                 \
    })

  const string& stamp_filename =
      NinjaGenerator::GetStampFilename(ninja_dir, ninja_suffix);
  FILE* fp = fopen(stamp_filename.c_str(), "rb+");
  if (!fp)
    RETURN_TRUE;
  ScopedFile sfp(fp);

  double gen_time;
  size_t r = fread(&gen_time, sizeof(gen_time), 1, fp);
  if (r != 1) {
    fprintf(stderr, "incomplete kati_stamp, regenerating...\n");
    RETURN_TRUE;
  }
  if (dump_kati_stamp)
    printf("Generated time: %f\n", gen_time);

  string s, s2;
  int num_files = LOAD_INT(fp);
  for (int i = 0; i < num_files; i++) {
    LOAD_STRING(fp, &s);
    double ts = GetTimestamp(s);
    if (gen_time < ts) {
      if (ignore_kati_binary) {
        string kati_binary;
        GetExecutablePath(&kati_binary);
        if (s == kati_binary) {
          fprintf(stderr, "%s was modified, ignored.\n", s.c_str());
          continue;
        }
      }
      if (ShouldIgnoreDirty(s)) {
        if (dump_kati_stamp)
          printf("file %s: ignored (%f)\n", s.c_str(), ts);
        continue;
      }
      if (dump_kati_stamp)
        printf("file %s: dirty (%f)\n", s.c_str(), ts);
      else
        fprintf(stderr, "%s was modified, regenerating...\n", s.c_str());
      RETURN_TRUE;
    } else if (dump_kati_stamp) {
      printf("file %s: clean (%f)\n", s.c_str(), ts);
    }
  }

  int num_undefineds = LOAD_INT(fp);
  for (int i = 0; i < num_undefineds; i++) {
    LOAD_STRING(fp, &s);
    if (getenv(s.c_str())) {
      if (dump_kati_stamp) {
        printf("env %s: dirty (unset => %s)\n", s.c_str(), getenv(s.c_str()));
      } else {
        fprintf(stderr, "Environment variable %s was set, regenerating...\n",
                s.c_str());
      }
      RETURN_TRUE;
    } else if (dump_kati_stamp) {
      printf("env %s: clean (unset)\n", s.c_str());
    }
  }

  int num_envs = LOAD_INT(fp);
  for (int i = 0; i < num_envs; i++) {
    LOAD_STRING(fp, &s);
    StringPiece val(getenv(s.c_str()));
    LOAD_STRING(fp, &s2);
    if (val != s2) {
      if (dump_kati_stamp) {
        printf("env %s: dirty (%s => %.*s)\n",
               s.c_str(), s2.c_str(), SPF(val));
      } else {
        fprintf(stderr, "Environment variable %s was modified (%s => %.*s), "
                "regenerating...\n",
                s.c_str(), s2.c_str(), SPF(val));
      }
      RETURN_TRUE;
    } else if (dump_kati_stamp) {
      printf("env %s: clean (%.*s)\n", s.c_str(), SPF(val));
    }
  }

  {
    int num_globs = LOAD_INT(fp);
    string pat;
    for (int i = 0; i < num_globs; i++) {
      COLLECT_STATS("glob time (regen)");
      LOAD_STRING(fp, &pat);
#if 0
      bool needs_reglob = false;
      int num_dirs = LOAD_INT(fp);
      for (int j = 0; j < num_dirs; j++) {
        LOAD_STRING(fp, &s);
        // TODO: Handle removed files properly.
        needs_reglob |= gen_time < GetTimestamp(s);
      }
#endif
      int num_files = LOAD_INT(fp);
      vector<string>* files;
      Glob(pat.c_str(), &files);
      sort(files->begin(), files->end());
      bool needs_regen = files->size() != static_cast<size_t>(num_files);
      for (int j = 0; j < num_files; j++) {
        LOAD_STRING(fp, &s);
        if (!needs_regen) {
          if ((*files)[j] != s) {
            needs_regen = true;
            break;
          }
        }
      }
      if (needs_regen) {
        if (ShouldIgnoreDirty(pat)) {
          if (dump_kati_stamp) {
            printf("wildcard %s: ignored\n", pat.c_str());
          }
          continue;
        }
        if (dump_kati_stamp) {
          printf("wildcard %s: dirty\n", pat.c_str());
        } else {
          fprintf(stderr, "wildcard(%s) was changed, regenerating...\n",
                  pat.c_str());
        }
        RETURN_TRUE;
      } else if (dump_kati_stamp) {
        printf("wildcard %s: clean\n", pat.c_str());
      }
    }
  }

  int num_crs = LOAD_INT(fp);
  for (int i = 0; i < num_crs; i++) {
    string cmd, expected;
    LOAD_STRING(fp, &cmd);
    LOAD_STRING(fp, &expected);

    {
      COLLECT_STATS("stat time (regen)");
      bool has_condition = LOAD_INT(fp);
      if (has_condition) {
        bool should_run_command = false;

        int num_missing_dirs = LOAD_INT(fp);
        for (int j = 0; j < num_missing_dirs; j++) {
          LOAD_STRING(fp, &s);
          should_run_command |= Exists(s);
        }

        int num_read_dirs = LOAD_INT(fp);
        for (int j = 0; j < num_read_dirs; j++) {
          LOAD_STRING(fp, &s);
          // We assume we rarely do a significant change for the top
          // directory which affects the results of find command.
          if (s == "" || s == "." || ShouldIgnoreDirty(s))
            continue;
          double ts = GetTimestamp(s);
          should_run_command |= (ts < 0 || gen_time < ts);
        }

        if (!should_run_command) {
          if (dump_kati_stamp)
            printf("shell %s: clean (no rerun)\n", cmd.c_str());
          continue;
        }
      }
    }

    FindCommand fc;
    if (fc.Parse(cmd) && !fc.chdir.empty() && ShouldIgnoreDirty(fc.chdir)) {
      if (dump_kati_stamp)
        printf("shell %s: ignored\n", cmd.c_str());
      continue;
    }

    {
      COLLECT_STATS_WITH_SLOW_REPORT("shell time (regen)", cmd.c_str());
      string result;
      RunCommand("/bin/sh", cmd, RedirectStderr::DEV_NULL, &result);
      FormatForCommandSubstitution(&result);
      if (expected != result) {
        if (dump_kati_stamp) {
          printf("shell %s: dirty\n", cmd.c_str());
        } else {
          fprintf(stderr, "$(shell %s) was changed, regenerating...\n",
                  cmd.c_str());
#if 0
          fprintf(stderr, "%s => %s\n",
                  expected.c_str(), result.c_str());
#endif
        }
        RETURN_TRUE;
      } else if (dump_kati_stamp) {
        printf("shell %s: clean (rerun)\n", cmd.c_str());
      }
    }
  }

  LoadString(fp, &s);
  if (orig_args != s) {
    fprintf(stderr, "arguments changed, regenerating...\n");
    RETURN_TRUE;
  }

  if (!retval) {
    if (fseek(fp, 0, SEEK_SET) < 0)
      PERROR("fseek");
    size_t r = fwrite(&start_time, sizeof(start_time), 1, fp);
    CHECK(r == 1);
  }

  return retval;
}
