// Copyright 2014 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 <sstream>

#include "gn/ninja_action_target_writer.h"
#include "gn/ninja_target_writer.h"
#include "gn/target.h"
#include "gn/test_with_scope.h"
#include "util/test/test.h"

namespace {

class TestingNinjaTargetWriter : public NinjaTargetWriter {
 public:
  TestingNinjaTargetWriter(const Target* target,
                           const Toolchain* toolchain,
                           std::ostream& out)
      : NinjaTargetWriter(target, out) {}

  void Run() override {}

  // Make this public so the test can call it.
  std::vector<OutputFile> WriteInputDepsPhonyAndGetDep(
      const std::vector<const Target*>& extra_hard_deps,
      size_t num_output_uses) {
    return NinjaTargetWriter::WriteInputDepsPhonyAndGetDep(extra_hard_deps,
                                                           num_output_uses);
  }
};

}  // namespace

TEST(NinjaTargetWriter, WriteInputDepsPhonyAndGetDep) {
  TestWithScope setup;
  Err err;

  // Make a base target that's a hard dep (action).
  Target base_target(setup.settings(), Label(SourceDir("//foo/"), "base"));
  base_target.set_output_type(Target::ACTION);
  base_target.visibility().SetPublic();
  base_target.SetToolchain(setup.toolchain());
  base_target.action_values().set_script(SourceFile("//foo/script.py"));

  // Dependent target that also includes a source prerequisite (should get
  // included) and a source (should not be included).
  Target target(setup.settings(), Label(SourceDir("//foo/"), "target"));
  target.set_output_type(Target::EXECUTABLE);
  target.visibility().SetPublic();
  target.SetToolchain(setup.toolchain());
  target.config_values().inputs().push_back(SourceFile("//foo/input.txt"));
  target.sources().push_back(SourceFile("//foo/source.txt"));
  target.public_deps().push_back(LabelTargetPair(&base_target));

  // Dependent action to test that action sources will be treated the same as
  // inputs.
  Target action(setup.settings(), Label(SourceDir("//foo/"), "action"));
  action.set_output_type(Target::ACTION);
  action.visibility().SetPublic();
  action.SetToolchain(setup.toolchain());
  action.action_values().set_script(SourceFile("//foo/script.py"));
  action.sources().push_back(SourceFile("//foo/action_source.txt"));
  action.public_deps().push_back(LabelTargetPair(&target));

  ASSERT_TRUE(base_target.OnResolved(&err));
  ASSERT_TRUE(target.OnResolved(&err));
  ASSERT_TRUE(action.OnResolved(&err));

  // Input deps for the base (should be only the script itself).
  {
    std::ostringstream stream;
    TestingNinjaTargetWriter writer(&base_target, setup.toolchain(), stream);
    std::vector<OutputFile> dep =
        writer.WriteInputDepsPhonyAndGetDep(std::vector<const Target*>(), 10u);

    // Since there is only one dependency, it should just be returned and
    // nothing written to the stream.
    ASSERT_EQ(1u, dep.size());
    EXPECT_EQ("../../foo/script.py", dep[0].value());
    EXPECT_EQ("", stream.str());
  }

  // Input deps for the target (should depend on the base).
  {
    std::ostringstream stream;
    TestingNinjaTargetWriter writer(&target, setup.toolchain(), stream);
    std::vector<OutputFile> dep =
        writer.WriteInputDepsPhonyAndGetDep(std::vector<const Target*>(), 10u);

    // Since there is only one dependency, a phony target will be returned
    // directly without writing any additional rules.
    ASSERT_EQ(1u, dep.size());
    EXPECT_EQ("phony/foo/base", dep[0].value());
  }

  {
    std::ostringstream stream;
    NinjaActionTargetWriter writer(&action, stream);
    writer.Run();
    EXPECT_EQ(
        "rule __foo_action___rule\n"
        "  command =  ../../foo/script.py\n"
        "  description = ACTION //foo:action()\n"
        "  restat = 1\n"
        "\n"
        "build: __foo_action___rule | ../../foo/script.py"
        " ../../foo/action_source.txt ./target\n"
        "\n"
        "build phony/foo/action: phony\n",
        stream.str());
  }

  // Input deps for action which should depend on the base since its a hard dep
  // that is a (indirect) dependency, as well as the the action source.
  {
    std::ostringstream stream;
    TestingNinjaTargetWriter writer(&action, setup.toolchain(), stream);
    std::vector<OutputFile> dep =
        writer.WriteInputDepsPhonyAndGetDep(std::vector<const Target*>(), 10u);

    ASSERT_EQ(1u, dep.size());
    EXPECT_EQ("phony/foo/action.inputdeps", dep[0].value());
    EXPECT_EQ(
        "build phony/foo/action.inputdeps: phony ../../foo/script.py "
        "../../foo/action_source.txt ./target\n",
        stream.str());
  }
}

// Tests WriteInputDepsPhonyAndGetDep when toolchain deps are present.
TEST(NinjaTargetWriter, WriteInputDepsPhonyAndGetDepWithToolchainDeps) {
  TestWithScope setup;
  Err err;

  // Toolchain dependency. Here we make a target in the same toolchain for
  // simplicity, but in real life (using the Builder) this would be rejected
  // because it would be a circular dependency (the target depends on its
  // toolchain, and the toolchain depends on this target).
  Target toolchain_dep_target(setup.settings(),
                              Label(SourceDir("//foo/"), "setup"));
  toolchain_dep_target.set_output_type(Target::ACTION);
  toolchain_dep_target.SetToolchain(setup.toolchain());
  ASSERT_TRUE(toolchain_dep_target.OnResolved(&err));
  setup.toolchain()->deps().push_back(LabelTargetPair(&toolchain_dep_target));

  // Make a binary target
  Target target(setup.settings(), Label(SourceDir("//foo/"), "target"));
  target.set_output_type(Target::EXECUTABLE);
  target.SetToolchain(setup.toolchain());
  ASSERT_TRUE(target.OnResolved(&err));

  std::ostringstream stream;
  TestingNinjaTargetWriter writer(&target, setup.toolchain(), stream);
  std::vector<OutputFile> dep =
      writer.WriteInputDepsPhonyAndGetDep(std::vector<const Target*>(), 10u);

  // Since there is more than one dependency, a phony target will be returned
  // and the rule for the phony target will be written to the stream.
  ASSERT_EQ(1u, dep.size());
  EXPECT_EQ("phony/foo/setup", dep[0].value());
  EXPECT_EQ("", stream.str());
}
