// Copyright (c) 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "gn/json_project_writer.h"

#include <algorithm>
#include <fstream>
#include <memory>
#include <unordered_map>
#include <vector>

#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/json/json_writer.h"
#include "base/json/string_escape.h"
#include "base/strings/string_number_conversions.h"
#include "gn/builder.h"
#include "gn/commands.h"
#include "gn/deps_iterator.h"
#include "gn/desc_builder.h"
#include "gn/exec_process.h"
#include "gn/filesystem_utils.h"
#include "gn/scheduler.h"
#include "gn/settings.h"
#include "gn/string_output_buffer.h"

// Structure of JSON output file
// {
//   "build_settings" : {
//     "root_path" : "absolute path of project root",
//     "build_dir" : "build directory (project relative)",
//     "default_toolchain" : "name of default toolchain"
//   }
//   "targets" : {
//      "target x full label" : { target x properties },
//      "target y full label" : { target y properties },
//      ...
//    }
// }
// See desc_builder.cc for overview of target properties

namespace {

void AddTargetDependencies(const Target* target, TargetSet* deps) {
  for (const auto& pair : target->GetDeps(Target::DEPS_LINKED)) {
    if (deps->add(pair.ptr)) {
      AddTargetDependencies(pair.ptr, deps);
    }
  }
}

// Filters targets according to filter string; Will also recursively
// add dependent targets.
bool FilterTargets(const BuildSettings* build_settings,
                   std::vector<const Target*>& all_targets,
                   std::vector<const Target*>* targets,
                   const std::string& dir_filter_string,
                   Err* err) {
  if (dir_filter_string.empty()) {
    *targets = all_targets;
  } else {
    targets->reserve(all_targets.size());
    std::vector<LabelPattern> filters;
    if (!commands::FilterPatternsFromString(build_settings, dir_filter_string,
                                            &filters, err)) {
      return false;
    }
    commands::FilterTargetsByPatterns(all_targets, filters, targets);

    TargetSet target_set(targets->begin(), targets->end());
    for (const auto* target : *targets)
      AddTargetDependencies(target, &target_set);

    targets->clear();
    targets->insert(targets->end(), target_set.begin(), target_set.end());
  }

  // Sort the list of targets per-label to get a consistent ordering of them
  // in the generated project (and thus stability of the file generated).
  std::sort(targets->begin(), targets->end(),
            [](const Target* a, const Target* b) {
              return a->label().name() < b->label().name();
            });

  return true;
}

bool InvokePython(const BuildSettings* build_settings,
                  const base::FilePath& python_script_path,
                  const std::string& python_script_extra_args,
                  const base::FilePath& output_path,
                  bool quiet,
                  Err* err) {
  const base::FilePath& python_path = build_settings->python_path();
  base::CommandLine cmdline(python_path);
  cmdline.AppendArg("--");
  cmdline.AppendArgPath(python_script_path);
  cmdline.AppendArgPath(output_path);
  if (!python_script_extra_args.empty()) {
    cmdline.AppendArg(python_script_extra_args);
  }
  base::FilePath startup_dir =
      build_settings->GetFullPath(build_settings->build_dir());

  std::string output;
  std::string stderr_output;

  int exit_code = 0;
  if (!internal::ExecProcess(cmdline, startup_dir, &output, &stderr_output,
                             &exit_code)) {
    *err =
        Err(Location(), "Could not execute python.",
            "I was trying to execute \"" + FilePathToUTF8(python_path) + "\".");
    return false;
  }

  if (!quiet) {
    printf("%s", output.c_str());
    fprintf(stderr, "%s", stderr_output.c_str());
  }

  if (exit_code != 0) {
    *err = Err(Location(), "Python has quit with exit code " +
                               base::IntToString(exit_code) + ".");
    return false;
  }

  return true;
}

}  // namespace

bool JSONProjectWriter::RunAndWriteFiles(
    const BuildSettings* build_settings,
    const Builder& builder,
    const std::string& file_name,
    const std::string& exec_script,
    const std::string& exec_script_extra_args,
    const std::string& dir_filter_string,
    bool quiet,
    Err* err) {
  SourceFile output_file = build_settings->build_dir().ResolveRelativeFile(
      Value(nullptr, file_name), err);
  if (output_file.is_null()) {
    return false;
  }

  base::FilePath output_path = build_settings->GetFullPath(output_file);

  std::vector<const Target*> all_targets = builder.GetAllResolvedTargets();
  std::vector<const Target*> targets;
  if (!FilterTargets(build_settings, all_targets, &targets, dir_filter_string,
                     err)) {
    return false;
  }

  StringOutputBuffer json = GenerateJSON(build_settings, targets);
  if (!json.ContentsEqual(output_path)) {
    if (!json.WriteToFile(output_path, err)) {
      return false;
    }

    if (!exec_script.empty()) {
      SourceFile script_file;
      if (exec_script[0] != '/') {
        // Relative path, assume the base is in build_dir.
        script_file = build_settings->build_dir().ResolveRelativeFile(
            Value(nullptr, exec_script), err);
        if (script_file.is_null()) {
          return false;
        }
      } else {
        script_file = SourceFile(exec_script);
      }
      base::FilePath script_path = build_settings->GetFullPath(script_file);
      return InvokePython(build_settings, script_path, exec_script_extra_args,
                          output_path, quiet, err);
    }
  }

  return true;
}

namespace {

// NOTE: Intentional macro definition allows compile-time string concatenation.
// (see usage below).
#if defined(OS_WINDOWS)
#define LINE_ENDING "\r\n"
#else
#define LINE_ENDING "\n"
#endif

// Helper class to output a, potentially very large, JSON file to a
// StringOutputBuffer. Note that sorting the keys, if desired, is left to
// the user (unlike base::JSONWriter). This allows rendering to be performed
// in series of incremental steps. Usage is:
//
//   1) Create instance, passing a StringOutputBuffer reference as the
//      destination.
//
//   2) Add keys and values using one of the following:
//
//       a) AddString(key, string_value) to add one string value.
//
//       b) BeginList(key), AddListItem(), EndList() to add a string list.
//          NOTE: Only lists of strings are supported here.
//
//       c) BeginDict(key), ... add other keys, followed by EndDict() to add
//          a dictionary key.
//
//   3) Call Close() or destroy the instance to finalize the output.
//
class SimpleJSONWriter {
 public:
  // Constructor.
  SimpleJSONWriter(StringOutputBuffer& out) : out_(out) {
    out_ << "{" LINE_ENDING;
    SetIndentation(1u);
  }

  // Destructor.
  ~SimpleJSONWriter() { Close(); }

  // Closing finalizes the output.
  void Close() {
    if (indentation_ > 0) {
      DCHECK(indentation_ == 1u);
      if (comma_.size())
        out_ << LINE_ENDING;

      out_ << "}" LINE_ENDING;
      SetIndentation(0);
    }
  }

  // Add new string-valued key.
  void AddString(std::string_view key, std::string_view value) {
    if (comma_.size()) {
      out_ << comma_;
    }
    AddMargin() << Escape(key) << ": " << Escape(value);
    comma_ = "," LINE_ENDING;
  }

  // Begin a new list. Must be followed by zero or more AddListItem() calls,
  // then by EndList().
  void BeginList(std::string_view key) {
    if (comma_.size())
      out_ << comma_;
    AddMargin() << Escape(key) << ": [ ";
    comma_ = {};
  }

  // Add a new list item. For now only string values are supported.
  void AddListItem(std::string_view item) {
    if (comma_.size())
      out_ << comma_;
    out_ << Escape(item);
    comma_ = ", ";
  }

  // End current list.
  void EndList() {
    out_ << " ]";
    comma_ = "," LINE_ENDING;
  }

  // Begin new dictionaary. Must be followed by zero or more other key
  // additions, then a call to EndDict().
  void BeginDict(std::string_view key) {
    if (comma_.size())
      out_ << comma_;

    AddMargin() << Escape(key) << ": {";
    SetIndentation(indentation_ + 1);
    comma_ = LINE_ENDING;
  }

  // End current dictionary.
  void EndDict() {
    if (comma_.size())
      out_ << LINE_ENDING;

    SetIndentation(indentation_ - 1);
    AddMargin() << "}";
    comma_ = "," LINE_ENDING;
  }

  // Add a dictionary-valued key, whose value is already formatted as a valid
  // JSON string. Useful to insert the output of base::JSONWriter::Write()
  // into the target buffer.
  void AddJSONDict(std::string_view key, std::string_view json) {
    if (comma_.size())
      out_ << comma_;
    AddMargin() << Escape(key) << ": ";
    if (json.empty()) {
      out_ << "{ }";
    } else {
      DCHECK(json[0] == '{');
      bool first_line = true;
      do {
        size_t line_end = json.find('\n');

        // NOTE: Do not add margin if original input line is empty.
        // This needs to deal with CR/LF which are part of |json| on Windows
        // only, due to the way base::JSONWriter::Write() is implemented.
        bool line_empty = (line_end == 0 || (line_end == 1 && json[0] == '\r'));
        if (!first_line && !line_empty)
          AddMargin();

        if (line_end == std::string_view::npos) {
          out_ << json;
          ;
          comma_ = {};
          return;
        }
        // Important: do not add the final newline.
        out_ << json.substr(
            0, (line_end == json.size() - 1) ? line_end : line_end + 1);
        json.remove_prefix(line_end + 1);
        first_line = false;
      } while (!json.empty());
    }
    comma_ = "," LINE_ENDING;
  }

 private:
  // Return the JSON-escape version of |str|.
  static std::string Escape(std::string_view str) {
    std::string result;
    base::EscapeJSONString(str, true, &result);
    return result;
  }

  // Adjust indentation level.
  void SetIndentation(size_t indentation) { indentation_ = indentation; }

  // Append margin, and return reference to output buffer.
  StringOutputBuffer& AddMargin() const {
    static const char kMargin[17] = "                ";
    size_t margin_len = indentation_ * 3;
    while (margin_len > 0) {
      size_t span = (margin_len > 16u) ? 16u : margin_len;
      out_.Append(kMargin, span);
      margin_len -= span;
    }
    return out_;
  }

  size_t indentation_ = 0;
  std::string_view comma_;
  StringOutputBuffer& out_;
};

}  // namespace

StringOutputBuffer JSONProjectWriter::GenerateJSON(
    const BuildSettings* build_settings,
    std::vector<const Target*>& all_targets) {
  Label default_toolchain_label;
  if (!all_targets.empty())
    default_toolchain_label =
        all_targets[0]->settings()->default_toolchain_label();

  StringOutputBuffer out;

  // Sort the targets according to their human visible labels first.
  std::unordered_map<const Target*, std::string> target_labels;
  for (const Target* target : all_targets) {
    target_labels[target] =
        target->label().GetUserVisibleName(default_toolchain_label);
  }

  std::vector<const Target*> sorted_targets(all_targets.begin(),
                                            all_targets.end());
  std::sort(sorted_targets.begin(), sorted_targets.end(),
            [&target_labels](const Target* a, const Target* b) {
              return target_labels[a] < target_labels[b];
            });

  SimpleJSONWriter json_writer(out);

  // IMPORTANT: Keep the keys sorted when adding them to |json_writer|.

  json_writer.BeginDict("build_settings");
  {
    json_writer.AddString("build_dir", build_settings->build_dir().value());

    json_writer.AddString("default_toolchain",
                          default_toolchain_label.GetUserVisibleName(false));

    json_writer.BeginList("gen_input_files");

    // Other files read by the build.
    std::vector<base::FilePath> other_files = g_scheduler->GetGenDependencies();

    const InputFileManager* input_file_manager =
        g_scheduler->input_file_manager();

    VectorSetSorter<base::FilePath> sorter(
        input_file_manager->GetInputFileCount() + other_files.size());

    input_file_manager->AddAllPhysicalInputFileNamesToVectorSetSorter(&sorter);

    sorter.Add(other_files.begin(), other_files.end());

    std::string build_path = FilePathToUTF8(build_settings->root_path());
    auto item_callback = [&json_writer,
                          &build_path](const base::FilePath& input_file) {
      std::string file;
      if (MakeAbsolutePathRelativeIfPossible(
              build_path, FilePathToUTF8(input_file), &file)) {
        json_writer.AddListItem(file);
      }
    };
    sorter.IterateOver(item_callback);

    json_writer.EndList();  // gen_input_files

    json_writer.AddString("root_path", build_settings->root_path_utf8());
  }
  json_writer.EndDict();  // build_settings

  std::map<Label, const Toolchain*> toolchains;
  json_writer.BeginDict("targets");
  {
    for (const auto* target : sorted_targets) {
      auto description =
          DescBuilder::DescriptionForTarget(target, "", false, false, false);
      // Outputs need to be asked for separately.
      auto outputs = DescBuilder::DescriptionForTarget(target, "source_outputs",
                                                       false, false, false);
      base::DictionaryValue* outputs_value = nullptr;
      if (outputs->GetDictionary("source_outputs", &outputs_value) &&
          !outputs_value->empty()) {
        description->MergeDictionary(outputs.get());
      }

      std::string json_dict;
      base::JSONWriter::WriteWithOptions(*description.get(),
                                         base::JSONWriter::OPTIONS_PRETTY_PRINT,
                                         &json_dict);
      json_writer.AddJSONDict(target_labels[target], json_dict);
      toolchains[target->toolchain()->label()] = target->toolchain();
    }
  }
  json_writer.EndDict();  // targets

  json_writer.BeginDict("toolchains");
  {
    for (const auto& tool_chain_kv : toolchains) {
      base::Value toolchain{base::Value::Type::DICTIONARY};
      const auto& tools = tool_chain_kv.second->tools();
      for (const auto& tool_kv : tools) {
        base::Value tool_info{base::Value::Type::DICTIONARY};
        auto setIfNotEmptry = [&](const auto& key, const auto& value) {
          if (value.size())
            tool_info.SetKey(key, base::Value{value});
        };
        auto setSubstitutionList = [&](const auto& key,
                                       const SubstitutionList& list) {
          if (list.list().empty())
            return;
          base::Value values{base::Value::Type::LIST};
          for (const auto& v : list.list())
            values.GetList().emplace_back(base::Value{v.AsString()});
          tool_info.SetKey(key, std::move(values));
        };
        const auto& tool = tool_kv.second;
        setIfNotEmptry("command", tool->command().AsString());
        setIfNotEmptry("command_launcher", tool->command_launcher());
        setIfNotEmptry("default_output_extension",
                       tool->default_output_extension());
        setIfNotEmptry("default_output_dir",
                       tool->default_output_dir().AsString());
        setIfNotEmptry("depfile", tool->depfile().AsString());
        setIfNotEmptry("description", tool->description().AsString());
        setIfNotEmptry("framework_switch", tool->framework_switch());
        setIfNotEmptry("weak_framework_switch", tool->weak_framework_switch());
        setIfNotEmptry("framework_dir_switch", tool->framework_dir_switch());
        setIfNotEmptry("lib_switch", tool->lib_switch());
        setIfNotEmptry("lib_dir_switch", tool->lib_dir_switch());
        setIfNotEmptry("linker_arg", tool->linker_arg());
        setSubstitutionList("outputs", tool->outputs());
        setSubstitutionList("partial_outputs", tool->partial_outputs());
        setSubstitutionList("runtime_outputs", tool->runtime_outputs());
        setIfNotEmptry("output_prefix", tool->output_prefix());

        toolchain.SetKey(tool_kv.first, std::move(tool_info));
      }
      std::string json_dict;
      base::JSONWriter::WriteWithOptions(
          toolchain, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json_dict);
      json_writer.AddJSONDict(tool_chain_kv.first.GetUserVisibleName(false), json_dict);
    }
  }
  json_writer.EndDict();  // toolchains

  json_writer.Close();

  return out;
}

std::string JSONProjectWriter::RenderJSON(
    const BuildSettings* build_settings,
    std::vector<const Target*>& all_targets) {
  StringOutputBuffer storage = GenerateJSON(build_settings, all_targets);
  return storage.str();
}
