// 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);
  }
  void Print(std::ostream& out, int indent) const override {}

 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));
}
