// 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 <algorithm>

#include "gn/builder.h"
#include "gn/config.h"
#include "gn/loader.h"
#include "gn/target.h"
#include "gn/test_with_scheduler.h"
#include "gn/test_with_scope.h"
#include "gn/toolchain.h"
#include "util/test/test.h"

namespace gn_builder_unittest {

class MockLoader : public Loader {
 public:
  MockLoader() = default;

  // Loader implementation:
  void Load(const SourceFile& file,
            const LocationRange& origin,
            const Label& toolchain_name) override {
    files_.push_back(file);
  }
  void ToolchainLoaded(const Toolchain* toolchain) override {}
  Label GetDefaultToolchain() const override { return Label(); }
  const Settings* GetToolchainSettings(const Label& label) const override {
    return nullptr;
  }
  SourceFile BuildFileForLabel(const Label& label) const override {
    return SourceFile(label.dir().value() + "BUILD.gn");
  }

  bool HasLoadedNone() const { return files_.empty(); }

  // Returns true if one/two loads have been requested and they match the given
  // file(s). This will clear the records so it will be empty for the next call.
  bool HasLoadedOne(const SourceFile& file) {
    if (files_.size() != 1u) {
      files_.clear();
      return false;
    }
    bool match = (files_[0] == file);
    files_.clear();
    return match;
  }
  bool HasLoadedTwo(const SourceFile& a, const SourceFile& b) {
    if (files_.size() != 2u) {
      files_.clear();
      return false;
    }

    bool match = ((files_[0] == a && files_[1] == b) ||
                  (files_[0] == b && files_[1] == a));
    files_.clear();
    return match;
  }
  bool HasLoadedOnce(const SourceFile& f) {
    return count(files_.begin(), files_.end(), f) == 1;
  }

 private:
  ~MockLoader() override = default;

  std::vector<SourceFile> files_;
};

class BuilderTest : public TestWithScheduler {
 public:
  BuilderTest()
      : loader_(new MockLoader),
        builder_(loader_.get()),
        settings_(&build_settings_, std::string()),
        scope_(&settings_) {
    build_settings_.SetBuildDir(SourceDir("//out/"));
    settings_.set_toolchain_label(Label(SourceDir("//tc/"), "default"));
    settings_.set_default_toolchain_label(settings_.toolchain_label());
  }

  Toolchain* DefineToolchain() {
    Toolchain* tc = new Toolchain(&settings_, settings_.toolchain_label());
    TestWithScope::SetupToolchain(tc);
    builder_.ItemDefined(std::unique_ptr<Item>(tc));
    return tc;
  }

 protected:
  scoped_refptr<MockLoader> loader_;
  Builder builder_;
  BuildSettings build_settings_;
  Settings settings_;
  Scope scope_;
};

TEST_F(BuilderTest, BasicDeps) {
  SourceDir toolchain_dir = settings_.toolchain_label().dir();
  std::string toolchain_name = settings_.toolchain_label().name();

  // Construct a dependency chain: A -> B -> C. Define A first with a
  // forward-reference to B, then C, then B to test the different orders that
  // the dependencies are hooked up.
  Label a_label(SourceDir("//a/"), "a", toolchain_dir, toolchain_name);
  Label b_label(SourceDir("//b/"), "b", toolchain_dir, toolchain_name);
  Label c_label(SourceDir("//c/"), "c", toolchain_dir, toolchain_name);

  // The builder will take ownership of the pointers.
  Target* a = new Target(&settings_, a_label);
  a->public_deps().push_back(LabelTargetPair(b_label));
  a->set_output_type(Target::EXECUTABLE);
  builder_.ItemDefined(std::unique_ptr<Item>(a));

  // Should have requested that B and the toolchain is loaded.
  EXPECT_TRUE(loader_->HasLoadedTwo(SourceFile("//tc/BUILD.gn"),
                                    SourceFile("//b/BUILD.gn")));

  // Define the toolchain.
  DefineToolchain();
  BuilderRecord* toolchain_record =
      builder_.GetRecord(settings_.toolchain_label());
  ASSERT_TRUE(toolchain_record);
  EXPECT_EQ(BuilderRecord::ITEM_TOOLCHAIN, toolchain_record->type());

  // A should be unresolved with an item
  BuilderRecord* a_record = builder_.GetRecord(a_label);
  EXPECT_TRUE(a_record->item());
  EXPECT_FALSE(a_record->resolved());
  EXPECT_FALSE(a_record->can_resolve());

  // B should be unresolved, have no item, and no deps.
  BuilderRecord* b_record = builder_.GetRecord(b_label);
  EXPECT_FALSE(b_record->item());
  EXPECT_FALSE(b_record->resolved());
  EXPECT_FALSE(b_record->can_resolve());
  EXPECT_TRUE(b_record->all_deps().empty());

  // A should have two deps: B and the toolchain. Only B should be unresolved.
  EXPECT_EQ(2u, a_record->all_deps().size());
  EXPECT_EQ(1u, a_record->unresolved_deps().size());
  EXPECT_NE(a_record->all_deps().end(),
            a_record->all_deps().find(toolchain_record));
  EXPECT_NE(a_record->all_deps().end(), a_record->all_deps().find(b_record));
  EXPECT_NE(a_record->unresolved_deps().end(),
            a_record->unresolved_deps().find(b_record));

  // B should be marked as having A waiting on it.
  EXPECT_EQ(1u, b_record->waiting_on_resolution().size());
  EXPECT_NE(b_record->waiting_on_resolution().end(),
            b_record->waiting_on_resolution().find(a_record));

  // Add the C target.
  Target* c = new Target(&settings_, c_label);
  c->set_output_type(Target::STATIC_LIBRARY);
  c->visibility().SetPublic();
  builder_.ItemDefined(std::unique_ptr<Item>(c));

  // C only depends on the already-loaded toolchain so we shouldn't have
  // requested anything else.
  EXPECT_TRUE(loader_->HasLoadedNone());

  // Add the B target.
  Target* b = new Target(&settings_, b_label);
  a->public_deps().push_back(LabelTargetPair(c_label));
  b->set_output_type(Target::SHARED_LIBRARY);
  b->visibility().SetPublic();
  builder_.ItemDefined(std::unique_ptr<Item>(b));

  // B depends only on the already-loaded C and toolchain so we shouldn't have
  // requested anything else.
  EXPECT_TRUE(loader_->HasLoadedNone());

  // All targets should now be resolved.
  BuilderRecord* c_record = builder_.GetRecord(c_label);
  EXPECT_TRUE(a_record->resolved());
  EXPECT_TRUE(b_record->resolved());
  EXPECT_TRUE(c_record->resolved());

  EXPECT_TRUE(a_record->unresolved_deps().empty());
  EXPECT_TRUE(b_record->unresolved_deps().empty());
  EXPECT_TRUE(c_record->unresolved_deps().empty());

  EXPECT_TRUE(a_record->waiting_on_resolution().empty());
  EXPECT_TRUE(b_record->waiting_on_resolution().empty());
  EXPECT_TRUE(c_record->waiting_on_resolution().empty());
}

// Tests that the "should generate" flag is set and propagated properly.
TEST_F(BuilderTest, ShouldGenerate) {
  DefineToolchain();

  // Define a secondary toolchain.
  Settings settings2(&build_settings_, "secondary/");
  Label toolchain_label2(SourceDir("//tc/"), "secondary");
  settings2.set_toolchain_label(toolchain_label2);
  Toolchain* tc2 = new Toolchain(&settings2, toolchain_label2);
  TestWithScope::SetupToolchain(tc2);
  builder_.ItemDefined(std::unique_ptr<Item>(tc2));

  // Construct a dependency chain: A -> B. A is in the default toolchain, B
  // is not.
  Label a_label(SourceDir("//foo/"), "a", settings_.toolchain_label().dir(),
                "a");
  Label b_label(SourceDir("//foo/"), "b", toolchain_label2.dir(),
                toolchain_label2.name());

  // First define B.
  Target* b = new Target(&settings2, b_label);
  b->visibility().SetPublic();
  b->set_output_type(Target::EXECUTABLE);
  builder_.ItemDefined(std::unique_ptr<Item>(b));

  // B should not be marked generated by default.
  BuilderRecord* b_record = builder_.GetRecord(b_label);
  EXPECT_FALSE(b_record->should_generate());

  // Define A with a dependency on B.
  Target* a = new Target(&settings_, a_label);
  a->public_deps().push_back(LabelTargetPair(b_label));
  a->set_output_type(Target::EXECUTABLE);
  builder_.ItemDefined(std::unique_ptr<Item>(a));

  // A should have the generate bit set since it's in the default toolchain.
  BuilderRecord* a_record = builder_.GetRecord(a_label);
  EXPECT_TRUE(a_record->should_generate());

  // It should have gotten pushed to B.
  EXPECT_TRUE(b_record->should_generate());
}

// Test that "gen_deps" forces targets to be generated.
TEST_F(BuilderTest, GenDeps) {
  DefineToolchain();

  // Define another toolchain
  Settings settings2(&build_settings_, "alternate/");
  Label alt_tc(SourceDir("//tc/"), "alternate");
  settings2.set_toolchain_label(alt_tc);
  Toolchain* tc2 = new Toolchain(&settings2, alt_tc);
  TestWithScope::SetupToolchain(tc2);
  builder_.ItemDefined(std::unique_ptr<Item>(tc2));

  // Construct the dependency chain A -> B -gen-> C -gen-> D where A is the only
  // target in the default toolchain. This should cause all 4 targets to be
  // generated.
  Label a_label(SourceDir("//a/"), "a", settings_.toolchain_label().dir(),
                settings_.toolchain_label().name());
  Label b_label(SourceDir("//b/"), "b", alt_tc.dir(), alt_tc.name());
  Label c_label(SourceDir("//c/"), "c", alt_tc.dir(), alt_tc.name());
  Label d_label(SourceDir("//d/"), "d", alt_tc.dir(), alt_tc.name());

  Target* c = new Target(&settings2, c_label);
  c->set_output_type(Target::EXECUTABLE);
  c->gen_deps().push_back(LabelTargetPair(d_label));
  builder_.ItemDefined(std::unique_ptr<Item>(c));

  Target* b = new Target(&settings2, b_label);
  b->set_output_type(Target::EXECUTABLE);
  b->gen_deps().push_back(LabelTargetPair(c_label));
  builder_.ItemDefined(std::unique_ptr<Item>(b));

  Target* a = new Target(&settings_, a_label);
  a->set_output_type(Target::EXECUTABLE);
  a->private_deps().push_back(LabelTargetPair(b_label));
  builder_.ItemDefined(std::unique_ptr<Item>(a));

  // At this point, "should generate" should have propogated to C which should
  // request for D to be loaded
  EXPECT_TRUE(loader_->HasLoadedOnce(SourceFile("//d/BUILD.gn")));

  Target* d = new Target(&settings2, d_label);
  d->set_output_type(Target::EXECUTABLE);
  builder_.ItemDefined(std::unique_ptr<Item>(d));

  BuilderRecord* a_record = builder_.GetRecord(a_label);
  BuilderRecord* b_record = builder_.GetRecord(b_label);
  BuilderRecord* c_record = builder_.GetRecord(c_label);
  BuilderRecord* d_record = builder_.GetRecord(d_label);
  EXPECT_TRUE(a_record->should_generate());
  EXPECT_TRUE(b_record->should_generate());
  EXPECT_TRUE(c_record->should_generate());
  EXPECT_TRUE(d_record->should_generate());
}

// Test that circular dependencies between gen_deps and deps are allowed
TEST_F(BuilderTest, GenDepsCircle) {
  DefineToolchain();
  Settings settings2(&build_settings_, "alternate/");
  Label alt_tc(SourceDir("//tc/"), "alternate");
  settings2.set_toolchain_label(alt_tc);
  Toolchain* tc2 = new Toolchain(&settings2, alt_tc);
  TestWithScope::SetupToolchain(tc2);
  builder_.ItemDefined(std::unique_ptr<Item>(tc2));

  // A is in the default toolchain and lists B as a gen_dep
  // B is in an alternate toolchain and lists A as a normal dep
  Label a_label(SourceDir("//a/"), "a", settings_.toolchain_label().dir(),
                settings_.toolchain_label().name());
  Label b_label(SourceDir("//b/"), "b", alt_tc.dir(), alt_tc.name());

  Target* a = new Target(&settings_, a_label);
  a->gen_deps().push_back(LabelTargetPair(b_label));
  a->set_output_type(Target::EXECUTABLE);
  builder_.ItemDefined(std::unique_ptr<Item>(a));

  Target* b = new Target(&settings2, b_label);
  b->private_deps().push_back(LabelTargetPair(a_label));
  b->set_output_type(Target::EXECUTABLE);
  builder_.ItemDefined(std::unique_ptr<Item>(b));

  Err err;
  EXPECT_TRUE(builder_.CheckForBadItems(&err));
  BuilderRecord* b_record = builder_.GetRecord(b_label);
  EXPECT_TRUE(b_record->should_generate());
}

// Tests that configs applied to a config get loaded (bug 536844).
TEST_F(BuilderTest, ConfigLoad) {
  SourceDir toolchain_dir = settings_.toolchain_label().dir();
  std::string toolchain_name = settings_.toolchain_label().name();

  // Construct a dependency chain: A -> B -> C. Define A first with a
  // forward-reference to B, then C, then B to test the different orders that
  // the dependencies are hooked up.
  Label a_label(SourceDir("//a/"), "a", toolchain_dir, toolchain_name);
  Label b_label(SourceDir("//b/"), "b", toolchain_dir, toolchain_name);
  Label c_label(SourceDir("//c/"), "c", toolchain_dir, toolchain_name);

  // The builder will take ownership of the pointers.
  Config* a = new Config(&settings_, a_label);
  a->configs().push_back(LabelConfigPair(b_label));
  builder_.ItemDefined(std::unique_ptr<Item>(a));

  // Should have requested that B is loaded.
  EXPECT_TRUE(loader_->HasLoadedOne(SourceFile("//b/BUILD.gn")));
}

}  // namespace gn_builder_unittest
