// Copyright 2015 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.syntax;

import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.lib.testutil.MoreAsserts.assertContainsEvent;

import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventCollector;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests of the Starlark validator. */
@RunWith(JUnit4.class)
public class ValidationTest {

  private final FileOptions.Builder options = FileOptions.builder();

  // Validates a file using the current options.
  private StarlarkFile validateFile(String... lines) throws SyntaxError {
    ParserInput input = ParserInput.fromLines(lines);
    Module module = Module.createForBuiltins(Starlark.UNIVERSE);
    return EvalUtils.parseAndValidate(input, options.build(), module);
  }

  // Assertions that parsing and validation succeeds.
  private void assertValid(String... lines) throws SyntaxError {
    StarlarkFile file = validateFile(lines);
    if (!file.ok()) {
      throw new SyntaxError(file.errors());
    }
  }

  // Asserts that parsing of the program succeeds but validation fails
  // with at least the specified error.
  private void assertInvalid(String expectedError, String... lines) throws SyntaxError {
    EventCollector errors = getValidationErrors(lines);
    assertContainsEvent(errors, expectedError);
  }

  // Returns the non-empty list of validation errors of the program.
  private EventCollector getValidationErrors(String... lines) throws SyntaxError {
    StarlarkFile file = validateFile(lines);
    if (file.ok()) {
      throw new AssertionError("validation succeeded unexpectedly");
    }
    EventCollector errors = new EventCollector();
    Event.replayEventsOn(errors, file.errors());
    return errors;
  }

  @Test
  public void testAssignmentNotValidLValue() throws Exception {
    assertInvalid("cannot assign to '\"a\"'", "'a' = 1");
  }

  @Test
  public void testAugmentedAssignmentWithMultipleLValues() throws Exception {
    assertInvalid(
        "cannot perform augmented assignment on a list or tuple expression", //
        "a, b += 2, 3");
  }

  @Test
  public void testReturnOutsideFunction() throws Exception {
    assertInvalid(
        "return statements must be inside a function", //
        "return 2\n");
  }

  @Test
  public void testLoadAfterStatement() throws Exception {
    options.requireLoadStatementsFirst(true);
    assertInvalid(
        "load() statements must be called before any other statement", //
        "a = 5",
        "load(':b.bzl', 'c')");
  }

  @Test
  public void testAllowLoadAfterStatement() throws Exception {
    options.requireLoadStatementsFirst(false);
    assertValid(
        "a = 5", //
        "load(':b.bzl', 'c')");
  }

  @Test
  public void testLoadDuplicateSymbols() throws Exception {
    assertInvalid(
        "load statement defines 'x' more than once", //
        "load('module', 'x', 'x')");
    assertInvalid(
        "load statement defines 'x' more than once", //
        "load('module', 'x', x='y')");

    // Eventually load bindings will be local,
    // at which point these errors will need adjusting.
    assertInvalid(
        "cannot reassign global 'x'", //
        "x=1; load('module', 'x')");
    assertInvalid(
        "cannot reassign global 'x'", //
        "load('module', 'x'); x=1");
  }

  @Test
  public void testForbiddenToplevelIfStatement() throws Exception {
    assertInvalid(
        "if statements are not allowed at the top level", //
        "if True: a = 2");
  }

  @Test
  public void testFunctionLocalVariable() throws Exception {
    assertInvalid(
        "name 'a' is not defined", //
        "def func2(b):",
        "  c = b",
        "  c = a",
        "def func1():",
        "  a = 1",
        "  func2(2)");
  }

  @Test
  public void testFunctionLocalVariableDoesNotEffectGlobalValidationEnv() throws Exception {
    assertInvalid(
        "name 'a' is not defined", //
        "def func1():",
        "  a = 1",
        "def func2(b):",
        "  b = a");
  }

  @Test
  public void testFunctionParameterDoesNotEffectGlobalValidationEnv() throws Exception {
    assertInvalid(
        "name 'a' is not defined", //
        "def func1(a):",
        "  return a",
        "def func2():",
        "  b = a");
  }

  @Test
  public void testDefinitionByItself() throws Exception {
    // Variables are assumed to be statically visible in the block (even if they might not be
    // initialized).
    assertValid("a = a");
    assertValid("a += a");
    assertValid("[[] for a in a]");
    assertValid("def f():", "  for a in a: pass");
  }

  @Test
  public void testLocalValidationEnvironmentsAreSeparated() throws Exception {
    assertValid(
        "def func1():", //
        "  a = 1",
        "def func2():",
        "  a = 'abc'");
  }

  @Test
  public void testBuiltinsCanBeShadowed() throws Exception {
    assertValid("repr = 1");
  }

  @Test
  public void testNoGlobalReassign() throws Exception {
    EventCollector errors = getValidationErrors("a = 1", "a = 2");
    assertContainsEvent(errors, ":2:1: cannot reassign global 'a'");
    assertContainsEvent(errors, ":1:1: 'a' previously declared here");
  }

  @Test
  public void testTwoFunctionsWithTheSameName() throws Exception {
    EventCollector errors = getValidationErrors("def foo(): pass", "def foo(): pass");
    assertContainsEvent(errors, ":2:5: cannot reassign global 'foo'");
    assertContainsEvent(errors, ":1:5: 'foo' previously declared here");
  }

  @Test
  public void testFunctionDefRecursion() throws Exception {
    assertValid("def func():", "  func()\n");
  }

  @Test
  public void testMutualRecursion() throws Exception {
    assertValid("def foo(i):", "  bar(i)", "def bar(i):", "  foo(i)", "foo(4)");
  }

  @Test
  public void testFunctionDefinedBelow() throws Exception {
    assertValid("def bar(): a = foo() + 'a'", "def foo(): return 1\n");
  }

  @Test
  public void testGlobalDefinedBelow() throws Exception {
    assertValid("def bar(): return x", "x = 5\n");
  }

  @Test
  public void testLocalVariableDefinedBelow() throws Exception {
    assertValid(
        "def bar():",
        "    for i in range(5):",
        "        if i > 2: return x",
        "        x = i" // x is visible in the entire function block
        );
  }

  @Test
  public void testFunctionDoesNotExist() throws Exception {
    assertInvalid(
        "name 'foo' is not defined", //
        "def bar(): a = foo() + 'a'");
  }

  @Test
  public void testTupleLiteralWorksForDifferentTypes() throws Exception {
    assertValid("('a', 1)");
  }

  @Test
  public void testDictExpressionDifferentValueTypeWorks() throws Exception {
    assertValid("{'a': 1, 'b': 'c'}");
  }

  @Test
  public void testNoneAssignment() throws Exception {
    assertValid("def func():", "  a = None", "  a = 2", "  a = None\n");
  }

  @Test
  public void testNoneIsAnyType() throws Exception {
    assertValid("None + None");
    assertValid("2 == None");
    assertValid("None > 'a'");
    assertValid("[] in None");
    assertValid("5 * None");
  }

  // Starlark built-in functions specific tests

  @Test
  public void testFuncReturningDictAssignmentAsLValue() throws Exception {
    assertValid(
        "def my_dict():", //
        "  return {'a': 1}",
        "def func():",
        "  my_dict()['b'] = 2");
  }

  @Test
  public void testEmptyLiteralGenericIsSetInLaterConcatWorks() throws Exception {
    assertValid(
        "def func():", //
        "  s = {}",
        "  s['a'] = 'b'");
  }

  @Test
  public void testModulesReadOnlyInFuncDefBody() throws Exception {
    assertValid("def func():", "  cmd_helper = depset()");
  }

  @Test
  public void testBuiltinGlobalFunctionsReadOnlyInFuncDefBody() throws Exception {
    assertValid("def func():", "  rule = 'abc'");
  }

  @Test
  public void testBuiltinGlobalFunctionsReadOnlyAsFuncDefArg() throws Exception {
    assertValid("def func(rule):", "  return rule");
  }

  @Test
  public void testFunctionReturnsFunction() throws Exception {
    assertValid(
        "def rule(*, implementation): return None", //
        "def impl(ctx): return None",
        "",
        "skylark_rule = rule(implementation = impl)",
        "",
        "def macro(name):",
        "  skylark_rule(name = name)");
  }

  @Test
  public void testTypeForBooleanLiterals() throws Exception {
    assertValid("len([1, 2]) == 0 and True");
    assertValid("len([1, 2]) == 0 and False");
  }

  @Test
  public void testDollarErrorDoesNotLeak() throws Exception {
    EventCollector errors =
        getValidationErrors(
            "def GenerateMapNames():", //
            "  a = 2",
            "  b = [3, 4]",
            "  if a not b:",
            "    print(a)");
    assertContainsEvent(errors, "syntax error at 'b': expected 'in'");
    // Parser uses "$error" symbol for error recovery.
    // It should not be used in error messages.
    for (Event event : errors) {
      assertThat(event.getMessage()).doesNotContain("$error$");
    }
  }

  @Test
  public void testPositionalAfterStarArg() throws Exception {
    assertInvalid(
        "positional argument is misplaced (positional arguments come first)", //
        "def fct(*args, **kwargs): pass",
        "fct(1, *[2], 3)");
  }

  @Test
  public void testTwoStarArgs() throws Exception {
    assertInvalid(
        "*arg argument is misplaced", //
        "def fct(*args, **kwargs):",
        "  pass",
        "fct(1, 2, 3, *[], *[])");
  }

  @Test
  public void testKeywordArgAfterStarArg() throws Exception {
    assertInvalid(
        "keyword argument is misplaced (keyword arguments must be before any *arg or **kwarg)", //
        "def fct(*args, **kwargs): pass",
        "fct(1, *[2], a=3)");
  }

  @Test
  public void testTopLevelForFails() throws Exception {
    assertInvalid(
        "for loops are not allowed at the top level", //
        "for i in []: 0\n");
  }

  @Test
  public void testNestedFunctionFails() throws Exception {
    assertInvalid(
        "nested functions are not allowed. Move the function to the top level", //
        "def func(a):",
        "  def bar(): return 0",
        "  return bar()",
        "");
  }
}
