// 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 <ostream>
#include <vector>

#include "base/bind.h"
#include "tools/gn/config.h"
#include "tools/gn/header_checker.h"
#include "tools/gn/scheduler.h"
#include "tools/gn/target.h"
#include "tools/gn/test_with_scheduler.h"
#include "tools/gn/test_with_scope.h"
#include "util/test/test.h"

namespace {

class HeaderCheckerTest : public TestWithScheduler {
 public:
  HeaderCheckerTest()
      : a_(setup_.settings(), Label(SourceDir("//a/"), "a")),
        b_(setup_.settings(), Label(SourceDir("//b/"), "b")),
        c_(setup_.settings(), Label(SourceDir("//c/"), "c")),
        d_(setup_.settings(), Label(SourceDir("//d/"), "d")) {
    a_.set_output_type(Target::SOURCE_SET);
    b_.set_output_type(Target::SOURCE_SET);
    c_.set_output_type(Target::SOURCE_SET);
    d_.set_output_type(Target::SOURCE_SET);

    Err err;
    a_.SetToolchain(setup_.toolchain(), &err);
    b_.SetToolchain(setup_.toolchain(), &err);
    c_.SetToolchain(setup_.toolchain(), &err);
    d_.SetToolchain(setup_.toolchain(), &err);

    a_.public_deps().push_back(LabelTargetPair(&b_));
    b_.public_deps().push_back(LabelTargetPair(&c_));

    // Start with all public visibility.
    a_.visibility().SetPublic();
    b_.visibility().SetPublic();
    c_.visibility().SetPublic();
    d_.visibility().SetPublic();

    d_.OnResolved(&err);
    c_.OnResolved(&err);
    b_.OnResolved(&err);
    a_.OnResolved(&err);

    targets_.push_back(&a_);
    targets_.push_back(&b_);
    targets_.push_back(&c_);
    targets_.push_back(&d_);
  }

 protected:
  TestWithScope setup_;

  // Some headers that are automatically set up with a public dependency chain.
  // a -> b -> c. D is unconnected.
  Target a_;
  Target b_;
  Target c_;
  Target d_;

  std::vector<const Target*> targets_;
};

}  // namespace

void PrintTo(const SourceFile& source_file, ::std::ostream* os) {
  *os << source_file.value();
}

TEST_F(HeaderCheckerTest, IsDependencyOf) {
  scoped_refptr<HeaderChecker> checker(
      new HeaderChecker(setup_.build_settings(), targets_));

  // Add a target P ("private") that privately depends on C, and hook up the
  // chain so that A -> P -> C. A will depend on C via two different paths.
  Err err;
  Target p(setup_.settings(), Label(SourceDir("//p/"), "p"));
  p.set_output_type(Target::SOURCE_SET);
  p.SetToolchain(setup_.toolchain(), &err);
  EXPECT_FALSE(err.has_error());
  p.private_deps().push_back(LabelTargetPair(&c_));
  p.visibility().SetPublic();
  p.OnResolved(&err);

  a_.public_deps().push_back(LabelTargetPair(&p));

  // A does not depend on itself.
  bool is_permitted = false;
  HeaderChecker::Chain chain;
  EXPECT_FALSE(checker->IsDependencyOf(&a_, &a_, &chain, &is_permitted));

  // A depends publicly on B.
  chain.clear();
  is_permitted = false;
  EXPECT_TRUE(checker->IsDependencyOf(&b_, &a_, &chain, &is_permitted));
  ASSERT_EQ(2u, chain.size());
  EXPECT_EQ(HeaderChecker::ChainLink(&b_, true), chain[0]);
  EXPECT_EQ(HeaderChecker::ChainLink(&a_, true), chain[1]);
  EXPECT_TRUE(is_permitted);

  // A indirectly depends on C. The "public" dependency path through B should
  // be identified.
  chain.clear();
  is_permitted = false;
  EXPECT_TRUE(checker->IsDependencyOf(&c_, &a_, &chain, &is_permitted));
  ASSERT_EQ(3u, chain.size());
  EXPECT_EQ(HeaderChecker::ChainLink(&c_, true), chain[0]);
  EXPECT_EQ(HeaderChecker::ChainLink(&b_, true), chain[1]);
  EXPECT_EQ(HeaderChecker::ChainLink(&a_, true), chain[2]);
  EXPECT_TRUE(is_permitted);

  // C does not depend on A.
  chain.clear();
  is_permitted = false;
  EXPECT_FALSE(checker->IsDependencyOf(&a_, &c_, &chain, &is_permitted));
  EXPECT_TRUE(chain.empty());
  EXPECT_FALSE(is_permitted);

  // Remove the B -> C public dependency, leaving P's private dep on C the only
  // path from A to C. This should now be found.
  chain.clear();
  EXPECT_EQ(&c_, b_.public_deps()[0].ptr);  // Validate it's the right one.
  b_.public_deps().erase(b_.public_deps().begin());
  EXPECT_TRUE(checker->IsDependencyOf(&c_, &a_, &chain, &is_permitted));
  EXPECT_EQ(3u, chain.size());
  EXPECT_EQ(HeaderChecker::ChainLink(&c_, false), chain[0]);
  EXPECT_EQ(HeaderChecker::ChainLink(&p, true), chain[1]);
  EXPECT_EQ(HeaderChecker::ChainLink(&a_, true), chain[2]);
  EXPECT_FALSE(is_permitted);

  // P privately depends on C. That dependency should be OK since it's only
  // one hop.
  chain.clear();
  is_permitted = false;
  EXPECT_TRUE(checker->IsDependencyOf(&c_, &p, &chain, &is_permitted));
  ASSERT_EQ(2u, chain.size());
  EXPECT_EQ(HeaderChecker::ChainLink(&c_, false), chain[0]);
  EXPECT_EQ(HeaderChecker::ChainLink(&p, true), chain[1]);
  EXPECT_TRUE(is_permitted);
}

TEST_F(HeaderCheckerTest, CheckInclude) {
  InputFile input_file(SourceFile("//some_file.cc"));
  input_file.SetContents(std::string());
  LocationRange range;  // Dummy value.

  // Add a disconnected target d with a header to check that you have to have
  // to depend on a target listing a header.
  SourceFile d_header("//d_header.h");
  d_.sources().push_back(SourceFile(d_header));

  // Add a header on B and say everything in B is public.
  SourceFile b_public("//b_public.h");
  b_.sources().push_back(b_public);
  c_.set_all_headers_public(true);

  // Add a public and private header on C.
  SourceFile c_public("//c_public.h");
  SourceFile c_private("//c_private.h");
  c_.sources().push_back(c_private);
  c_.public_headers().push_back(c_public);
  c_.set_all_headers_public(false);

  // Create another toolchain.
  Settings other_settings(setup_.build_settings(), "other/");
  Toolchain other_toolchain(&other_settings,
                            Label(SourceDir("//toolchain/"), "other"));
  TestWithScope::SetupToolchain(&other_toolchain);
  other_settings.set_toolchain_label(other_toolchain.label());
  other_settings.set_default_toolchain_label(setup_.toolchain()->label());

  // Add a target in the other toolchain with a header in it that is not
  // connected to any targets in the main toolchain.
  Target otc(&other_settings,
             Label(SourceDir("//p/"), "otc", other_toolchain.label().dir(),
                   other_toolchain.label().name()));
  otc.set_output_type(Target::SOURCE_SET);
  Err err;
  EXPECT_TRUE(otc.SetToolchain(&other_toolchain, &err));
  otc.visibility().SetPublic();
  targets_.push_back(&otc);

  SourceFile otc_header("//otc_header.h");
  otc.sources().push_back(otc_header);
  EXPECT_TRUE(otc.OnResolved(&err));

  scoped_refptr<HeaderChecker> checker(
      new HeaderChecker(setup_.build_settings(), targets_));

  std::set<std::pair<const Target*, const Target*>> no_dependency_cache;
  // A file in target A can't include a header from D because A has no
  // dependency on D.
  std::vector<Err> errors;
  checker->CheckInclude(&a_, input_file, d_header, range, &no_dependency_cache,
                        &errors);
  EXPECT_GT(errors.size(), 0);

  // A can include the public header in B.
  errors.clear();
  no_dependency_cache.clear();
  checker->CheckInclude(&a_, input_file, b_public, range, &no_dependency_cache,
                        &errors);
  EXPECT_EQ(errors.size(), 0);

  // Check A depending on the public and private headers in C.
  errors.clear();
  no_dependency_cache.clear();
  checker->CheckInclude(&a_, input_file, c_public, range, &no_dependency_cache,
                        &errors);
  EXPECT_EQ(errors.size(), 0);
  errors.clear();
  no_dependency_cache.clear();
  checker->CheckInclude(&a_, input_file, c_private, range, &no_dependency_cache,
                        &errors);
  EXPECT_GT(errors.size(), 0);

  // A can depend on a random file unknown to the build.
  errors.clear();
  no_dependency_cache.clear();
  checker->CheckInclude(&a_, input_file, SourceFile("//random.h"), range,
                        &no_dependency_cache, &errors);
  EXPECT_EQ(errors.size(), 0);

  // A can depend on a file present only in another toolchain even with no
  // dependency path.
  errors.clear();
  no_dependency_cache.clear();
  checker->CheckInclude(&a_, input_file, otc_header, range,
                        &no_dependency_cache, &errors);
  EXPECT_EQ(errors.size(), 0);
}

// A public chain of dependencies should always be identified first, even if
// it is longer than a private one.
TEST_F(HeaderCheckerTest, PublicFirst) {
  // Now make a A -> Z -> D private dependency chain (one shorter than the
  // public one to get to D).
  Target z(setup_.settings(), Label(SourceDir("//a/"), "a"));
  z.set_output_type(Target::SOURCE_SET);
  Err err;
  EXPECT_TRUE(z.SetToolchain(setup_.toolchain(), &err));
  z.private_deps().push_back(LabelTargetPair(&d_));
  EXPECT_TRUE(z.OnResolved(&err));
  targets_.push_back(&z);

  a_.private_deps().push_back(LabelTargetPair(&z));

  // Check that D can be found from A, but since it's private, it will be
  // marked as not permitted.
  bool is_permitted = false;
  HeaderChecker::Chain chain;
  scoped_refptr<HeaderChecker> checker(
      new HeaderChecker(setup_.build_settings(), targets_));
  EXPECT_TRUE(checker->IsDependencyOf(&d_, &a_, &chain, &is_permitted));

  EXPECT_FALSE(is_permitted);
  ASSERT_EQ(3u, chain.size());
  EXPECT_EQ(HeaderChecker::ChainLink(&d_, false), chain[0]);
  EXPECT_EQ(HeaderChecker::ChainLink(&z, false), chain[1]);
  EXPECT_EQ(HeaderChecker::ChainLink(&a_, true), chain[2]);

  // Hook up D to the existing public A -> B -> C chain to make a long one, and
  // search for D again.
  c_.public_deps().push_back(LabelTargetPair(&d_));
  checker = new HeaderChecker(setup_.build_settings(), targets_);
  chain.clear();
  EXPECT_TRUE(checker->IsDependencyOf(&d_, &a_, &chain, &is_permitted));

  // This should have found the long public one.
  EXPECT_TRUE(is_permitted);
  ASSERT_EQ(4u, chain.size());
  EXPECT_EQ(HeaderChecker::ChainLink(&d_, true), chain[0]);
  EXPECT_EQ(HeaderChecker::ChainLink(&c_, true), chain[1]);
  EXPECT_EQ(HeaderChecker::ChainLink(&b_, true), chain[2]);
  EXPECT_EQ(HeaderChecker::ChainLink(&a_, true), chain[3]);
}

// Checks that the allow_circular_includes_from list works.
TEST_F(HeaderCheckerTest, CheckIncludeAllowCircular) {
  InputFile input_file(SourceFile("//some_file.cc"));
  input_file.SetContents(std::string());
  LocationRange range;  // Dummy value.

  // Add an include file to A.
  SourceFile a_public("//a_public.h");
  a_.sources().push_back(a_public);

  scoped_refptr<HeaderChecker> checker(
      new HeaderChecker(setup_.build_settings(), targets_));

  // A depends on B. So B normally can't include headers from A.
  std::vector<Err> errors;
  std::set<std::pair<const Target*, const Target*>> no_dependency_cache;
  checker->CheckInclude(&b_, input_file, a_public, range, &no_dependency_cache,
                        &errors);
  EXPECT_GT(errors.size(), 0);

  // Add an allow_circular_includes_from on A that lists B.
  a_.allow_circular_includes_from().insert(b_.label());

  // Now the include from B to A should be allowed.
  errors.clear();
  no_dependency_cache.clear();
  checker->CheckInclude(&b_, input_file, a_public, range, &no_dependency_cache,
                        &errors);
  EXPECT_EQ(errors.size(), 0);
}

TEST_F(HeaderCheckerTest, SourceFileForInclude) {
  using base::FilePath;
  const std::vector<SourceDir> kIncludeDirs = {
      SourceDir("/c/custom_include/"), SourceDir("//"), SourceDir("//subdir")};
  a_.sources().push_back(SourceFile("//lib/header1.h"));
  b_.sources().push_back(SourceFile("/c/custom_include/header2.h"));

  InputFile dummy_input_file(SourceFile("//some_file.cc"));
  dummy_input_file.SetContents(std::string());
  LocationRange dummy_range;

  scoped_refptr<HeaderChecker> checker(
      new HeaderChecker(setup_.build_settings(), targets_));
  {
    Err err;
    SourceFile source_file = checker->SourceFileForInclude(
        "lib/header1.h", kIncludeDirs, dummy_input_file, dummy_range, &err);
    EXPECT_FALSE(err.has_error());
    EXPECT_EQ(SourceFile("//lib/header1.h"), source_file);
  }

  {
    Err err;
    SourceFile source_file = checker->SourceFileForInclude(
        "header2.h", kIncludeDirs, dummy_input_file, dummy_range, &err);
    EXPECT_FALSE(err.has_error());
    EXPECT_EQ(SourceFile("/c/custom_include/header2.h"), source_file);
  }
}

TEST_F(HeaderCheckerTest, SourceFileForInclude_FileNotFound) {
  using base::FilePath;
  const char kFileContents[] = "Some dummy contents";
  const std::vector<SourceDir> kIncludeDirs = {SourceDir("//")};
  scoped_refptr<HeaderChecker> checker(
      new HeaderChecker(setup_.build_settings(), targets_));

  Err err;
  InputFile input_file(SourceFile("//input.cc"));
  input_file.SetContents(std::string(kFileContents));
  const int kLineNumber = 10;
  const int kColumnNumber = 16;
  const int kLength = 8;
  const int kByteNumber = 100;
  LocationRange range(
      Location(&input_file, kLineNumber, kColumnNumber, kByteNumber),
      Location(&input_file, kLineNumber, kColumnNumber + kLength, kByteNumber));

  SourceFile source_file = checker->SourceFileForInclude(
      "header.h", kIncludeDirs, input_file, range, &err);
  EXPECT_TRUE(source_file.is_null());
  EXPECT_FALSE(err.has_error());
}

TEST_F(HeaderCheckerTest, Friend) {
  // Note: we have a public dependency chain A -> B -> C set up already.
  InputFile input_file(SourceFile("//some_file.cc"));
  input_file.SetContents(std::string());
  LocationRange range;  // Dummy value.

  // Add a private header on C.
  SourceFile c_private("//c_private.h");
  c_.sources().push_back(c_private);
  c_.set_all_headers_public(false);

  // List A as a friend of C.
  Err err;
  c_.friends().push_back(
      LabelPattern::GetPattern(SourceDir("//"), Value(nullptr, "//a:*"), &err));
  ASSERT_FALSE(err.has_error());

  // Must be after setting everything up for it to find the files.
  scoped_refptr<HeaderChecker> checker(
      new HeaderChecker(setup_.build_settings(), targets_));

  // B should not be allowed to include C's private header.
  std::vector<Err> errors;
  std::set<std::pair<const Target*, const Target*>> no_dependency_cache;
  checker->CheckInclude(&b_, input_file, c_private, range, &no_dependency_cache,
                        &errors);
  EXPECT_GT(errors.size(), 0);

  // A should be able to because of the friend declaration.
  errors.clear();
  no_dependency_cache.clear();
  checker->CheckInclude(&a_, input_file, c_private, range, &no_dependency_cache,
                        &errors);
  EXPECT_EQ(errors.size(), 0);
}
