// 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);
  base::StringPiece 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"));
}
