// Copyright (c) 2013 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 "tools/gn/test_with_scope.h"

#include <memory>
#include <utility>

#include "base/bind.h"
#include "tools/gn/parser.h"
#include "tools/gn/tokenizer.h"

namespace {

BuildSettings CreateBuildSettingsForTest() {
  BuildSettings build_settings;
  build_settings.SetBuildDir(SourceDir("//out/Debug/"));
  return build_settings;
}

}  // namespace

TestWithScope::TestWithScope()
    : build_settings_(CreateBuildSettingsForTest()),
      settings_(&build_settings_, std::string()),
      toolchain_(&settings_, Label(SourceDir("//toolchain/"), "default")),
      scope_(&settings_),
      scope_progammatic_provider_(&scope_, true) {
  build_settings_.set_print_callback(
      base::Bind(&TestWithScope::AppendPrintOutput, base::Unretained(this)));

  settings_.set_toolchain_label(toolchain_.label());
  settings_.set_default_toolchain_label(toolchain_.label());

  SetupToolchain(&toolchain_);
  scope_.set_item_collector(&items_);
}

TestWithScope::~TestWithScope() = default;

Label TestWithScope::ParseLabel(const std::string& str) const {
  Err err;
  Label result = Label::Resolve(SourceDir("//"), toolchain_.label(),
                                Value(nullptr, str), &err);
  CHECK(!err.has_error());
  return result;
}

bool TestWithScope::ExecuteSnippet(const std::string& str, Err* err) {
  TestParseInput input(str);
  if (input.has_error()) {
    *err = input.parse_err();
    return false;
  }

  size_t first_item = items_.size();
  input.parsed()->Execute(&scope_, err);
  if (err->has_error())
    return false;

  for (size_t i = first_item; i < items_.size(); ++i) {
    CHECK(items_[i]->AsTarget() != nullptr)
        << "Only targets are supported in ExecuteSnippet()";
    items_[i]->AsTarget()->SetToolchain(&toolchain_);
    if (!items_[i]->OnResolved(err))
      return false;
  }
  return true;
}

// static
void TestWithScope::SetupToolchain(Toolchain* toolchain) {
  Err err;

  // CC
  std::unique_ptr<Tool> cc_tool = Tool::CreateTool(CTool::kCToolCc);
  SetCommandForTool(
      "cc {{source}} {{cflags}} {{cflags_c}} {{defines}} {{include_dirs}} "
      "-o {{output}}",
      cc_tool.get());
  cc_tool->set_outputs(SubstitutionList::MakeForTest(
      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o"));
  toolchain->SetTool(std::move(cc_tool));

  // CXX
  std::unique_ptr<Tool> cxx_tool = Tool::CreateTool(CTool::kCToolCxx);
  SetCommandForTool(
      "c++ {{source}} {{cflags}} {{cflags_cc}} {{defines}} {{include_dirs}} "
      "-o {{output}}",
      cxx_tool.get());
  cxx_tool->set_outputs(SubstitutionList::MakeForTest(
      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o"));
  toolchain->SetTool(std::move(cxx_tool));

  // OBJC
  std::unique_ptr<Tool> objc_tool = Tool::CreateTool(CTool::kCToolObjC);
  SetCommandForTool(
      "objcc {{source}} {{cflags}} {{cflags_objc}} {{defines}} "
      "{{include_dirs}} -o {{output}}",
      objc_tool.get());
  objc_tool->set_outputs(SubstitutionList::MakeForTest(
      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o"));
  toolchain->SetTool(std::move(objc_tool));

  // OBJC
  std::unique_ptr<Tool> objcxx_tool = Tool::CreateTool(CTool::kCToolObjCxx);
  SetCommandForTool(
      "objcxx {{source}} {{cflags}} {{cflags_objcc}} {{defines}} "
      "{{include_dirs}} -o {{output}}",
      objcxx_tool.get());
  objcxx_tool->set_outputs(SubstitutionList::MakeForTest(
      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o"));
  toolchain->SetTool(std::move(objcxx_tool));

  // Don't use RC and ASM tools in unit tests yet. Add here if needed.

  // ALINK
  std::unique_ptr<Tool> alink = Tool::CreateTool(CTool::kCToolAlink);
  CTool* alink_tool = alink->AsC();
  SetCommandForTool("ar {{output}} {{source}}", alink_tool);
  alink_tool->set_lib_switch("-l");
  alink_tool->set_lib_dir_switch("-L");
  alink_tool->set_output_prefix("lib");
  alink_tool->set_outputs(SubstitutionList::MakeForTest(
      "{{target_out_dir}}/{{target_output_name}}.a"));
  toolchain->SetTool(std::move(alink));

  // SOLINK
  std::unique_ptr<Tool> solink = Tool::CreateTool(CTool::kCToolSolink);
  CTool* solink_tool = solink->AsC();
  SetCommandForTool(
      "ld -shared -o {{target_output_name}}.so {{inputs}} "
      "{{ldflags}} {{libs}}",
      solink_tool);
  solink_tool->set_lib_switch("-l");
  solink_tool->set_lib_dir_switch("-L");
  solink_tool->set_output_prefix("lib");
  solink_tool->set_default_output_extension(".so");
  solink_tool->set_outputs(SubstitutionList::MakeForTest(
      "{{root_out_dir}}/{{target_output_name}}{{output_extension}}"));
  toolchain->SetTool(std::move(solink));

  // SOLINK_MODULE
  std::unique_ptr<Tool> solink_module =
      Tool::CreateTool(CTool::kCToolSolinkModule);
  CTool* solink_module_tool = solink_module->AsC();
  SetCommandForTool(
      "ld -bundle -o {{target_output_name}}.so {{inputs}} "
      "{{ldflags}} {{libs}}",
      solink_module_tool);
  solink_module_tool->set_lib_switch("-l");
  solink_module_tool->set_lib_dir_switch("-L");
  solink_module_tool->set_output_prefix("lib");
  solink_module_tool->set_default_output_extension(".so");
  solink_module_tool->set_outputs(SubstitutionList::MakeForTest(
      "{{root_out_dir}}/{{target_output_name}}{{output_extension}}"));
  toolchain->SetTool(std::move(solink_module));

  // LINK
  std::unique_ptr<Tool> link = Tool::CreateTool(CTool::kCToolLink);
  CTool* link_tool = link->AsC();
  SetCommandForTool(
      "ld -o {{target_output_name}} {{source}} "
      "{{ldflags}} {{libs}}",
      link_tool);
  link_tool->set_lib_switch("-l");
  link_tool->set_lib_dir_switch("-L");
  link_tool->set_outputs(
      SubstitutionList::MakeForTest("{{root_out_dir}}/{{target_output_name}}"));
  toolchain->SetTool(std::move(link));

  // STAMP
  std::unique_ptr<Tool> stamp_tool =
      Tool::CreateTool(GeneralTool::kGeneralToolStamp);
  SetCommandForTool("touch {{output}}", stamp_tool.get());
  toolchain->SetTool(std::move(stamp_tool));

  // COPY
  std::unique_ptr<Tool> copy_tool =
      Tool::CreateTool(GeneralTool::kGeneralToolCopy);
  SetCommandForTool("cp {{source}} {{output}}", copy_tool.get());
  toolchain->SetTool(std::move(copy_tool));

  // COPY_BUNDLE_DATA
  std::unique_ptr<Tool> copy_bundle_data_tool =
      Tool::CreateTool(GeneralTool::kGeneralToolCopyBundleData);
  SetCommandForTool("cp {{source}} {{output}}", copy_bundle_data_tool.get());
  toolchain->SetTool(std::move(copy_bundle_data_tool));

  // COMPILE_XCASSETS
  std::unique_ptr<Tool> compile_xcassets_tool =
      Tool::CreateTool(GeneralTool::kGeneralToolCompileXCAssets);
  SetCommandForTool("touch {{output}}", compile_xcassets_tool.get());
  toolchain->SetTool(std::move(compile_xcassets_tool));

  toolchain->ToolchainSetupComplete();
}

// static
void TestWithScope::SetCommandForTool(const std::string& cmd, Tool* tool) {
  Err err;
  SubstitutionPattern command;
  command.Parse(cmd, nullptr, &err);
  CHECK(!err.has_error()) << "Couldn't parse \"" << cmd << "\", "
                          << "got " << err.message();
  tool->set_command(command);
}

void TestWithScope::AppendPrintOutput(const std::string& str) {
  print_output_.append(str);
}

TestParseInput::TestParseInput(const std::string& input)
    : input_file_(SourceFile("//test")) {
  input_file_.SetContents(input);

  tokens_ = Tokenizer::Tokenize(&input_file_, &parse_err_);
  if (!parse_err_.has_error())
    parsed_ = Parser::Parse(tokens_, &parse_err_);
}

TestParseInput::~TestParseInput() = default;

TestTarget::TestTarget(const TestWithScope& setup,
                       const std::string& label_string,
                       Target::OutputType type)
    : Target(setup.settings(), setup.ParseLabel(label_string)) {
  visibility().SetPublic();
  set_output_type(type);
  SetToolchain(setup.toolchain());
}

TestTarget::~TestTarget() = default;
