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

#include <stdint.h>

#include <memory>
#include <utility>

#include "tools/gn/parse_tree.h"
#include "tools/gn/pattern.h"
#include "tools/gn/test_with_scope.h"
#include "util/test/test.h"

namespace {

bool IsValueIntegerEqualing(const Value& v, int64_t i) {
  if (v.type() != Value::INTEGER)
    return false;
  return v.int_value() == i;
}

bool IsValueStringEqualing(const Value& v, const char* s) {
  if (v.type() != Value::STRING)
    return false;
  return v.string_value() == s;
}

// This parse node is for passing to tests. It returns a canned value for
// Execute().
class TestParseNode : public ParseNode {
 public:
  TestParseNode(const Value& v) : value_(v) {}

  Value Execute(Scope* scope, Err* err) const override { return value_; }
  LocationRange GetRange() const override { return LocationRange(); }
  Err MakeErrorDescribing(const std::string& msg,
                          const std::string& help) const override {
    return Err(this, msg);
  }
  base::Value GetJSONNode() const override {
    return base::Value();
  }

 private:
  Value value_;
};

// Sets up a BinaryOpNode for testing.
class TestBinaryOpNode : public BinaryOpNode {
 public:
  // Input token value string must outlive class.
  TestBinaryOpNode(Token::Type op_token_type, const char* op_token_value)
      : BinaryOpNode(),
        op_token_ownership_(Location(), op_token_type, op_token_value) {
    set_op(op_token_ownership_);
  }

  void SetLeftToValue(const Value& value) {
    set_left(std::make_unique<TestParseNode>(value));
  }

  // Sets the left-hand side of the operator to an identifier node, this is
  // used for testing assignments. Input string must outlive class.
  void SetLeftToIdentifier(const char* identifier) {
    left_identifier_token_ownership_ =
        Token(Location(), Token::IDENTIFIER, identifier);
    set_left(
        std::make_unique<IdentifierNode>(left_identifier_token_ownership_));
  }

  void SetRightToValue(const Value& value) {
    set_right(std::make_unique<TestParseNode>(value));
  }
  void SetRightToListOfValue(const Value& value) {
    Value list(nullptr, Value::LIST);
    list.list_value().push_back(value);
    set_right(std::make_unique<TestParseNode>(list));
  }
  void SetRightToListOfValue(const Value& value1, const Value& value2) {
    Value list(nullptr, Value::LIST);
    list.list_value().push_back(value1);
    list.list_value().push_back(value2);
    set_right(std::make_unique<TestParseNode>(list));
  }

 private:
  // The base class takes the Token by reference, this manages the lifetime.
  Token op_token_ownership_;

  // When setting the left to an identifier, this manages the lifetime of
  // the identifier token.
  Token left_identifier_token_ownership_;
};

}  // namespace

TEST(Operators, SourcesAppend) {
  Err err;
  TestWithScope setup;

  // Set up "sources" with an empty list.
  const char sources[] = "sources";
  setup.scope()->SetValue(sources, Value(nullptr, Value::LIST), nullptr);

  // Set up the operator.
  TestBinaryOpNode node(Token::PLUS_EQUALS, "+=");
  node.SetLeftToIdentifier(sources);

  // Set up the filter on the scope to remove everything ending with "rm"
  std::unique_ptr<PatternList> pattern_list = std::make_unique<PatternList>();
  pattern_list->Append(Pattern("*rm"));
  setup.scope()->set_sources_assignment_filter(std::move(pattern_list));

  // Append an integer.
  node.SetRightToListOfValue(Value(nullptr, static_cast<int64_t>(5)));
  node.Execute(setup.scope(), &err);
  EXPECT_FALSE(err.has_error());

  // Append a string that doesn't match the pattern, it should get appended.
  const char string1[] = "good";
  node.SetRightToListOfValue(Value(nullptr, string1));
  node.Execute(setup.scope(), &err);
  EXPECT_FALSE(err.has_error());

  // Append a string that does match the pattern, it should be a no-op.
  const char string2[] = "foo-rm";
  node.SetRightToListOfValue(Value(nullptr, string2));
  node.Execute(setup.scope(), &err);
  EXPECT_FALSE(err.has_error());

  // Append a list with the two strings from above.
  node.SetRightToListOfValue(Value(nullptr, string1), Value(nullptr, string2));
  node.Execute(setup.scope(), &err);
  EXPECT_FALSE(err.has_error());

  // The sources variable in the scope should now have: [ 5, "good", "good" ]
  const Value* value = setup.scope()->GetValue(sources);
  ASSERT_TRUE(value);
  ASSERT_EQ(Value::LIST, value->type());
  ASSERT_EQ(3u, value->list_value().size());
  EXPECT_TRUE(IsValueIntegerEqualing(value->list_value()[0], 5));
  EXPECT_TRUE(IsValueStringEqualing(value->list_value()[1], "good"));
  EXPECT_TRUE(IsValueStringEqualing(value->list_value()[2], "good"));
}

// Note that the SourcesAppend test above tests the basic list + list features,
// this test handles the other cases.
TEST(Operators, ListAppend) {
  Err err;
  TestWithScope setup;

  // Set up "foo" with an empty list.
  const char foo[] = "foo";
  setup.scope()->SetValue(foo, Value(nullptr, Value::LIST), nullptr);

  // Set up the operator to append to "foo".
  TestBinaryOpNode node(Token::PLUS_EQUALS, "+=");
  node.SetLeftToIdentifier(foo);

  // Append a list with a list, the result should be a nested list.
  Value inner_list(nullptr, Value::LIST);
  inner_list.list_value().push_back(Value(nullptr, static_cast<int64_t>(12)));
  node.SetRightToListOfValue(inner_list);

  Value ret = ExecuteBinaryOperator(setup.scope(), &node, node.left(),
                                    node.right(), &err);
  EXPECT_FALSE(err.has_error());

  // Return from the operator should always be "none", it should update the
  // value only.
  EXPECT_EQ(Value::NONE, ret.type());

  // The value should be updated with "[ [ 12 ] ]"
  Value result = *setup.scope()->GetValue(foo);
  ASSERT_EQ(Value::LIST, result.type());
  ASSERT_EQ(1u, result.list_value().size());
  ASSERT_EQ(Value::LIST, result.list_value()[0].type());
  ASSERT_EQ(1u, result.list_value()[0].list_value().size());
  ASSERT_EQ(Value::INTEGER, result.list_value()[0].list_value()[0].type());
  ASSERT_EQ(12, result.list_value()[0].list_value()[0].int_value());

  // Try to append an integer and a string directly (e.g. foo += "hi").
  // This should fail.
  const char str_str[] = "\"hi\"";
  Token str(Location(), Token::STRING, str_str);
  node.set_right(std::make_unique<LiteralNode>(str));
  ExecuteBinaryOperator(setup.scope(), &node, node.left(), node.right(), &err);
  EXPECT_TRUE(err.has_error());
  err = Err();

  node.SetRightToValue(Value(nullptr, static_cast<int64_t>(12)));
  ExecuteBinaryOperator(setup.scope(), &node, node.left(), node.right(), &err);
  EXPECT_TRUE(err.has_error());
}

TEST(Operators, ListRemove) {
  Err err;
  TestWithScope setup;

  const char foo_str[] = "foo";
  const char bar_str[] = "bar";
  Value test_list(nullptr, Value::LIST);
  test_list.list_value().push_back(Value(nullptr, foo_str));
  test_list.list_value().push_back(Value(nullptr, bar_str));
  test_list.list_value().push_back(Value(nullptr, foo_str));

  // Set up "var" with an the test list.
  const char var[] = "var";
  setup.scope()->SetValue(var, test_list, nullptr);

  TestBinaryOpNode node(Token::MINUS_EQUALS, "-=");
  node.SetLeftToIdentifier(var);

  // Subtract a list consisting of "foo".
  node.SetRightToListOfValue(Value(nullptr, foo_str));
  Value result = ExecuteBinaryOperator(setup.scope(), &node, node.left(),
                                       node.right(), &err);
  EXPECT_FALSE(err.has_error());

  // -= returns an empty value to reduce the possibility of writing confusing
  // cases like foo = bar += 1.
  EXPECT_EQ(Value::NONE, result.type());

  // The "var" variable should have been updated. Both instances of "foo" are
  // deleted.
  const Value* new_value = setup.scope()->GetValue(var);
  ASSERT_TRUE(new_value);
  ASSERT_EQ(Value::LIST, new_value->type());
  ASSERT_EQ(1u, new_value->list_value().size());
  ASSERT_EQ(Value::STRING, new_value->list_value()[0].type());
  EXPECT_EQ("bar", new_value->list_value()[0].string_value());
}

TEST(Operators, ListSubtractWithScope) {
  Err err;
  TestWithScope setup;

  Scope* scope_a = new Scope(setup.settings());
  Value scopeval_a(nullptr, std::unique_ptr<Scope>(scope_a));
  scope_a->SetValue("a", Value(nullptr, "foo"), nullptr);

  Scope* scope_b = new Scope(setup.settings());
  Value scopeval_b(nullptr, std::unique_ptr<Scope>(scope_b));
  scope_b->SetValue("b", Value(nullptr, "bar"), nullptr);

  Value lval(nullptr, Value::LIST);
  lval.list_value().push_back(scopeval_a);
  lval.list_value().push_back(scopeval_b);

  Scope* scope_a_other = new Scope(setup.settings());
  Value scopeval_a_other(nullptr, std::unique_ptr<Scope>(scope_a_other));
  scope_a_other->SetValue("a", Value(nullptr, "foo"), nullptr);

  Value rval(nullptr, Value::LIST);
  rval.list_value().push_back(scopeval_a_other);

  TestBinaryOpNode node(Token::MINUS, "-");
  node.SetLeftToValue(lval);
  node.SetRightToValue(rval);
  Value ret = ExecuteBinaryOperator(setup.scope(), &node, node.left(),
                                    node.right(), &err);
  ASSERT_FALSE(err.has_error());
  ASSERT_EQ(Value::LIST, ret.type());

  std::vector<Value> expected;
  Scope* scope_expected = new Scope(setup.settings());
  Value scopeval_expected(nullptr, std::unique_ptr<Scope>(scope_expected));
  scope_expected->SetValue("b", Value(nullptr, "bar"), nullptr);
  expected.push_back(scopeval_expected);
  EXPECT_EQ(expected, ret.list_value());
}

TEST(Operators, IntegerAdd) {
  Err err;
  TestWithScope setup;

  TestBinaryOpNode node(Token::PLUS, "+");
  node.SetLeftToValue(Value(nullptr, static_cast<int64_t>(123)));
  node.SetRightToValue(Value(nullptr, static_cast<int64_t>(456)));
  Value ret = ExecuteBinaryOperator(setup.scope(), &node, node.left(),
                                    node.right(), &err);
  ASSERT_FALSE(err.has_error());
  ASSERT_EQ(Value::INTEGER, ret.type());
  EXPECT_EQ(579, ret.int_value());
}

TEST(Operators, IntegerSubtract) {
  Err err;
  TestWithScope setup;

  TestBinaryOpNode node(Token::MINUS, "-");
  node.SetLeftToValue(Value(nullptr, static_cast<int64_t>(123)));
  node.SetRightToValue(Value(nullptr, static_cast<int64_t>(456)));
  Value ret = ExecuteBinaryOperator(setup.scope(), &node, node.left(),
                                    node.right(), &err);
  ASSERT_FALSE(err.has_error());
  ASSERT_EQ(Value::INTEGER, ret.type());
  EXPECT_EQ(-333, ret.int_value());
}

TEST(Operators, ShortCircuitAnd) {
  Err err;
  TestWithScope setup;

  // Set a && operator with the left to false.
  TestBinaryOpNode node(Token::BOOLEAN_AND, "&&");
  node.SetLeftToValue(Value(nullptr, false));

  // Set right as foo, but don't define a value for it.
  const char foo[] = "foo";
  Token identifier_token(Location(), Token::IDENTIFIER, foo);
  node.set_right(std::make_unique<IdentifierNode>(identifier_token));

  Value ret = ExecuteBinaryOperator(setup.scope(), &node, node.left(),
                                    node.right(), &err);
  EXPECT_FALSE(err.has_error());
}

TEST(Operators, ShortCircuitOr) {
  Err err;
  TestWithScope setup;

  // Set a || operator with the left to true.
  TestBinaryOpNode node(Token::BOOLEAN_OR, "||");
  node.SetLeftToValue(Value(nullptr, true));

  // Set right as foo, but don't define a value for it.
  const char foo[] = "foo";
  Token identifier_token(Location(), Token::IDENTIFIER, foo);
  node.set_right(std::make_unique<IdentifierNode>(identifier_token));

  Value ret = ExecuteBinaryOperator(setup.scope(), &node, node.left(),
                                    node.right(), &err);
  EXPECT_FALSE(err.has_error());
}

// Overwriting nonempty lists and scopes with other nonempty lists and scopes
// should be disallowed.
TEST(Operators, NonemptyOverwriting) {
  Err err;
  TestWithScope setup;

  // Set up "foo" with a nonempty list.
  const char foo[] = "foo";
  Value old_value(nullptr, Value::LIST);
  old_value.list_value().push_back(Value(nullptr, "string"));
  setup.scope()->SetValue(foo, old_value, nullptr);

  TestBinaryOpNode node(Token::EQUAL, "=");
  node.SetLeftToIdentifier(foo);

  // Assigning a nonempty list should fail.
  node.SetRightToListOfValue(Value(nullptr, "string"));
  node.Execute(setup.scope(), &err);
  ASSERT_TRUE(err.has_error());
  EXPECT_EQ("Replacing nonempty list.", err.message());
  err = Err();

  // Assigning an empty list should succeed.
  node.SetRightToValue(Value(nullptr, Value::LIST));
  node.Execute(setup.scope(), &err);
  ASSERT_FALSE(err.has_error());
  const Value* new_value = setup.scope()->GetValue(foo);
  ASSERT_TRUE(new_value);
  ASSERT_EQ(Value::LIST, new_value->type());
  ASSERT_TRUE(new_value->list_value().empty());

  // Set up "foo" with a nonempty scope.
  const char bar[] = "bar";
  old_value = Value(nullptr, std::make_unique<Scope>(setup.settings()));
  old_value.scope_value()->SetValue(bar, Value(nullptr, "bar"), nullptr);
  setup.scope()->SetValue(foo, old_value, nullptr);

  // Assigning a nonempty scope should fail (re-use old_value copy).
  node.SetRightToValue(old_value);
  node.Execute(setup.scope(), &err);
  ASSERT_TRUE(err.has_error());
  EXPECT_EQ("Replacing nonempty scope.", err.message());
  err = Err();

  // Assigning an empty list should succeed.
  node.SetRightToValue(
      Value(nullptr, std::make_unique<Scope>(setup.settings())));
  node.Execute(setup.scope(), &err);
  ASSERT_FALSE(err.has_error());
  new_value = setup.scope()->GetValue(foo);
  ASSERT_TRUE(new_value);
  ASSERT_EQ(Value::SCOPE, new_value->type());
  ASSERT_FALSE(new_value->scope_value()->HasValues(Scope::SEARCH_CURRENT));
}

// Tests this case:
//  foo = 1
//  target(...) {
//    foo += 1
//
// This should mark the outer "foo" as used, and the inner "foo" as unused.
TEST(Operators, PlusEqualsUsed) {
  Err err;
  TestWithScope setup;

  // Outer "foo" definition, it should be unused.
  const char foo[] = "foo";
  Value old_value(nullptr, static_cast<int64_t>(1));
  setup.scope()->SetValue(foo, old_value, nullptr);
  EXPECT_TRUE(setup.scope()->IsSetButUnused(foo));

  // Nested scope.
  Scope nested(setup.scope());

  // Run "foo += 1".
  TestBinaryOpNode node(Token::PLUS_EQUALS, "+=");
  node.SetLeftToIdentifier(foo);
  node.SetRightToValue(Value(nullptr, static_cast<int64_t>(1)));
  node.Execute(&nested, &err);
  ASSERT_FALSE(err.has_error());

  // Outer foo should be used, inner foo should not be.
  EXPECT_FALSE(setup.scope()->IsSetButUnused(foo));
  EXPECT_TRUE(nested.IsSetButUnused(foo));
}
