// 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/scope.h"

#include "tools/gn/input_file.h"
#include "tools/gn/parse_tree.h"
#include "tools/gn/source_file.h"
#include "tools/gn/template.h"
#include "tools/gn/test_with_scope.h"
#include "util/test/test.h"

namespace {

bool HasStringValueEqualTo(const Scope* scope,
                           const char* name,
                           const char* expected_value) {
  const Value* value = scope->GetValue(name);
  if (!value)
    return false;
  if (value->type() != Value::STRING)
    return false;
  return value->string_value() == expected_value;
}

bool ContainsBuildDependencyFile(const Scope* scope,
                                 const SourceFile& source_file) {
  const auto& build_dependency_files = scope->build_dependency_files();
  return build_dependency_files.end() !=
         build_dependency_files.find(source_file);
}

}  // namespace

TEST(Scope, InheritBuildDependencyFilesFromParent) {
  TestWithScope setup;
  SourceFile source_file = SourceFile("//a/BUILD.gn");
  setup.scope()->AddBuildDependencyFile(source_file);

  Scope new_scope(setup.scope());
  EXPECT_EQ(1U, new_scope.build_dependency_files().size());
  EXPECT_TRUE(ContainsBuildDependencyFile(&new_scope, source_file));
}

TEST(Scope, NonRecursiveMergeTo) {
  TestWithScope setup;

  // Make a pretend parse node with proper tracking that we can blame for the
  // given value.
  InputFile input_file(SourceFile("//foo"));
  Token assignment_token(Location(&input_file, 1, 1, 1), Token::STRING,
                         "\"hello\"");
  LiteralNode assignment;
  assignment.set_value(assignment_token);

  // Add some values to the scope.
  Value old_value(&assignment, "hello");
  setup.scope()->SetValue("v", old_value, &assignment);
  std::string_view private_var_name("_private");
  setup.scope()->SetValue(private_var_name, old_value, &assignment);

  // Add some templates to the scope.
  FunctionCallNode templ_definition;
  scoped_refptr<Template> templ(new Template(setup.scope(), &templ_definition));
  setup.scope()->AddTemplate("templ", templ.get());
  scoped_refptr<Template> private_templ(
      new Template(setup.scope(), &templ_definition));
  setup.scope()->AddTemplate("_templ", private_templ.get());

  // Detect collisions of values' values.
  {
    Scope new_scope(setup.settings());
    Value new_value(&assignment, "goodbye");
    new_scope.SetValue("v", new_value, &assignment);

    Err err;
    EXPECT_FALSE(setup.scope()->NonRecursiveMergeTo(
        &new_scope, Scope::MergeOptions(), &assignment, "error", &err));
    EXPECT_TRUE(err.has_error());
  }

  // Template name collisions.
  {
    Scope new_scope(setup.settings());

    scoped_refptr<Template> new_templ(
        new Template(&new_scope, &templ_definition));
    new_scope.AddTemplate("templ", new_templ.get());

    Err err;
    EXPECT_FALSE(setup.scope()->NonRecursiveMergeTo(
        &new_scope, Scope::MergeOptions(), &assignment, "error", &err));
    EXPECT_TRUE(err.has_error());
  }

  // The clobber flag should just overwrite colliding values.
  {
    Scope new_scope(setup.settings());
    Value new_value(&assignment, "goodbye");
    new_scope.SetValue("v", new_value, &assignment);

    Err err;
    Scope::MergeOptions options;
    options.clobber_existing = true;
    EXPECT_TRUE(setup.scope()->NonRecursiveMergeTo(&new_scope, options,
                                                   &assignment, "error", &err));
    EXPECT_FALSE(err.has_error());

    const Value* found_value = new_scope.GetValue("v");
    ASSERT_TRUE(found_value);
    EXPECT_TRUE(old_value == *found_value);
  }

  // Clobber flag for templates.
  {
    Scope new_scope(setup.settings());

    scoped_refptr<Template> new_templ(
        new Template(&new_scope, &templ_definition));
    new_scope.AddTemplate("templ", new_templ.get());
    Scope::MergeOptions options;
    options.clobber_existing = true;

    Err err;
    EXPECT_TRUE(setup.scope()->NonRecursiveMergeTo(&new_scope, options,
                                                   &assignment, "error", &err));
    EXPECT_FALSE(err.has_error());

    const Template* found_value = new_scope.GetTemplate("templ");
    ASSERT_TRUE(found_value);
    EXPECT_TRUE(templ.get() == found_value);
  }

  // Don't flag values that technically collide but have the same value.
  {
    Scope new_scope(setup.settings());
    Value new_value(&assignment, "hello");
    new_scope.SetValue("v", new_value, &assignment);

    Err err;
    EXPECT_TRUE(setup.scope()->NonRecursiveMergeTo(
        &new_scope, Scope::MergeOptions(), &assignment, "error", &err));
    EXPECT_FALSE(err.has_error());
  }

  // Templates that technically collide but are the same.
  {
    Scope new_scope(setup.settings());

    scoped_refptr<Template> new_templ(
        new Template(&new_scope, &templ_definition));
    new_scope.AddTemplate("templ", templ.get());

    Err err;
    EXPECT_TRUE(setup.scope()->NonRecursiveMergeTo(
        &new_scope, Scope::MergeOptions(), &assignment, "error", &err));
    EXPECT_FALSE(err.has_error());
  }

  // Copy private values and templates.
  {
    Scope new_scope(setup.settings());

    Err err;
    EXPECT_TRUE(setup.scope()->NonRecursiveMergeTo(
        &new_scope, Scope::MergeOptions(), &assignment, "error", &err));
    EXPECT_FALSE(err.has_error());
    EXPECT_TRUE(new_scope.GetValue(private_var_name));
    EXPECT_TRUE(new_scope.GetTemplate("_templ"));
  }

  // Skip private values and templates.
  {
    Scope new_scope(setup.settings());

    Err err;
    Scope::MergeOptions options;
    options.skip_private_vars = true;
    EXPECT_TRUE(setup.scope()->NonRecursiveMergeTo(&new_scope, options,
                                                   &assignment, "error", &err));
    EXPECT_FALSE(err.has_error());
    EXPECT_FALSE(new_scope.GetValue(private_var_name));
    EXPECT_FALSE(new_scope.GetTemplate("_templ"));
  }

  // Don't mark used.
  {
    Scope new_scope(setup.settings());

    Err err;
    Scope::MergeOptions options;
    EXPECT_TRUE(setup.scope()->NonRecursiveMergeTo(&new_scope, options,
                                                   &assignment, "error", &err));
    EXPECT_FALSE(err.has_error());
    EXPECT_FALSE(new_scope.CheckForUnusedVars(&err));
    EXPECT_TRUE(err.has_error());
  }

  // Mark dest used.
  {
    Scope new_scope(setup.settings());

    Err err;
    Scope::MergeOptions options;
    options.mark_dest_used = true;
    EXPECT_TRUE(setup.scope()->NonRecursiveMergeTo(&new_scope, options,
                                                   &assignment, "error", &err));
    EXPECT_FALSE(err.has_error());
    EXPECT_TRUE(new_scope.CheckForUnusedVars(&err));
    EXPECT_FALSE(err.has_error());
  }

  // Build dependency files are merged.
  {
    Scope from_scope(setup.settings());
    SourceFile source_file = SourceFile("//a/BUILD.gn");
    from_scope.AddBuildDependencyFile(source_file);

    Scope to_scope(setup.settings());
    EXPECT_FALSE(ContainsBuildDependencyFile(&to_scope, source_file));

    Scope::MergeOptions options;
    Err err;
    EXPECT_TRUE(from_scope.NonRecursiveMergeTo(&to_scope, options, &assignment,
                                               "error", &err));
    EXPECT_FALSE(err.has_error());
    EXPECT_EQ(1U, to_scope.build_dependency_files().size());
    EXPECT_TRUE(ContainsBuildDependencyFile(&to_scope, source_file));
  }
}

TEST(Scope, MakeClosure) {
  // Create 3 nested scopes [const root from setup] <- nested1 <- nested2.
  TestWithScope setup;

  // Make a pretend parse node with proper tracking that we can blame for the
  // given value.
  InputFile input_file(SourceFile("//foo"));
  Token assignment_token(Location(&input_file, 1, 1, 1), Token::STRING,
                         "\"hello\"");
  LiteralNode assignment;
  assignment.set_value(assignment_token);
  setup.scope()->SetValue("on_root", Value(&assignment, "on_root"),
                          &assignment);

  // Root scope should be const from the nested caller's perspective.
  Scope nested1(static_cast<const Scope*>(setup.scope()));
  nested1.SetValue("on_one", Value(&assignment, "on_one"), &assignment);

  Scope nested2(&nested1);
  nested2.SetValue("on_one", Value(&assignment, "on_two"), &assignment);
  nested2.SetValue("on_two", Value(&assignment, "on_two2"), &assignment);

  // Making a closure from the root scope.
  std::unique_ptr<Scope> result = setup.scope()->MakeClosure();
  EXPECT_FALSE(result->containing());        // Should have no containing scope.
  EXPECT_TRUE(result->GetValue("on_root"));  // Value should be copied.

  // Making a closure from the second nested scope.
  result = nested2.MakeClosure();
  EXPECT_EQ(setup.scope(),
            result->containing());  // Containing scope should be the root.
  EXPECT_TRUE(HasStringValueEqualTo(result.get(), "on_root", "on_root"));
  EXPECT_TRUE(HasStringValueEqualTo(result.get(), "on_one", "on_two"));
  EXPECT_TRUE(HasStringValueEqualTo(result.get(), "on_two", "on_two2"));
}

TEST(Scope, GetMutableValue) {
  TestWithScope setup;

  // Make a pretend parse node with proper tracking that we can blame for the
  // given value.
  InputFile input_file(SourceFile("//foo"));
  Token assignment_token(Location(&input_file, 1, 1, 1), Token::STRING,
                         "\"hello\"");
  LiteralNode assignment;
  assignment.set_value(assignment_token);

  const char kOnConst[] = "on_const";
  const char kOnMutable1[] = "on_mutable1";
  const char kOnMutable2[] = "on_mutable2";

  Value value(&assignment, "hello");

  // Create a root scope with one value.
  Scope root_scope(setup.settings());
  root_scope.SetValue(kOnConst, value, &assignment);

  // Create a first nested scope with a different value.
  const Scope* const_root_scope = &root_scope;
  Scope mutable_scope1(const_root_scope);
  mutable_scope1.SetValue(kOnMutable1, value, &assignment);

  // Create a second nested scope with a different value.
  Scope mutable_scope2(&mutable_scope1);
  mutable_scope2.SetValue(kOnMutable2, value, &assignment);

  // Check getting root scope values.
  EXPECT_TRUE(mutable_scope2.GetValue(kOnConst, true));
  EXPECT_FALSE(
      mutable_scope2.GetMutableValue(kOnConst, Scope::SEARCH_NESTED, true));

  // Test reading a value from scope 1.
  Value* mutable1_result =
      mutable_scope2.GetMutableValue(kOnMutable1, Scope::SEARCH_NESTED, false);
  ASSERT_TRUE(mutable1_result);
  EXPECT_TRUE(*mutable1_result == value);

  // Make sure CheckForUnusedVars works on scope1 (we didn't mark the value as
  // used in the previous step).
  Err err;
  EXPECT_FALSE(mutable_scope1.CheckForUnusedVars(&err));
  mutable1_result =
      mutable_scope2.GetMutableValue(kOnMutable1, Scope::SEARCH_NESTED, true);
  EXPECT_TRUE(mutable1_result);
  err = Err();
  EXPECT_TRUE(mutable_scope1.CheckForUnusedVars(&err));

  // Test reading a value from scope 2.
  Value* mutable2_result =
      mutable_scope2.GetMutableValue(kOnMutable2, Scope::SEARCH_NESTED, true);
  ASSERT_TRUE(mutable2_result);
  EXPECT_TRUE(*mutable2_result == value);
}

TEST(Scope, RemovePrivateIdentifiers) {
  TestWithScope setup;
  setup.scope()->SetValue("a", Value(nullptr, true), nullptr);
  setup.scope()->SetValue("_b", Value(nullptr, true), nullptr);

  setup.scope()->RemovePrivateIdentifiers();
  EXPECT_TRUE(setup.scope()->GetValue("a"));
  EXPECT_FALSE(setup.scope()->GetValue("_b"));
}
