// 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 com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventKind;
import com.google.devtools.build.lib.events.util.EventCollectionApparatus;
import com.google.devtools.build.lib.testutil.TestMode;
import org.junit.Before;
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 {

  // TODO(adonovan): make this not depend on StarlarkThread.

  private final EventCollectionApparatus events =
      new EventCollectionApparatus(EventKind.ALL_EVENTS);
  private StarlarkThread thread;

  @Before
  public void initialize() throws Exception {
    thread = newStarlarkThread();
  }

  private StarlarkThread newStarlarkThread(String... options) throws Exception {
    return TestMode.SKYLARK.createStarlarkThread(events.reporter(), ImmutableMap.of(), options);
  }

  private void parseFile(String... lines) {
    ParserInput input = ParserInput.fromLines(lines);
    StarlarkFile file = EvalUtils.parseAndValidateSkylark(input, thread);
    Event.replayEventsOn(events.reporter(), file.errors());
  }

  private void setFailFast(boolean failFast) {
    events.setFailFast(failFast);
  }

  private Event assertContainsError(String expectedMessage) {
    return events.assertContainsError(expectedMessage);
  }

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

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

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

  @Test
  public void testLoadAfterStatement() throws Exception {
    thread = newStarlarkThread("--incompatible_bzl_disallow_load_after_statement=true");
    checkError(
        "load() statements must be called before any other statement",
        "a = 5",
        "load(':b.bzl', 'c')");
  }

  @Test
  public void testAllowLoadAfterStatement() throws Exception {
    thread = newStarlarkThread("--incompatible_bzl_disallow_load_after_statement=false");
    parse("a = 5", "load(':b.bzl', 'c')");
  }

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

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

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

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

  @Test
  public void testFunctionParameterDoesNotEffectGlobalValidationEnv() throws Exception {
    checkError("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).
    parse("a = a");
    parse("a += a");
    parse("[[] for a in a]");
    parse("def f():", "  for a in a: pass");
  }

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

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

  @Test
  public void testNoGlobalReassign() throws Exception {
    setFailFast(false);
    parseFile("a = 1", "a = 2");
    assertContainsError(":2:1: cannot reassign global 'a'");
    assertContainsError(":1:1: 'a' previously declared here");
  }

  @Test
  public void testTwoFunctionsWithTheSameName() throws Exception {
    setFailFast(false);
    parseFile("def foo(): pass", "def foo(): pass");
    assertContainsError(":2:5: cannot reassign global 'foo'");
    assertContainsError(":1:5: 'foo' previously declared here");
  }

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

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

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

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

  @Test
  public void testLocalVariableDefinedBelow() throws Exception {
    parse(
        "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() {
    checkError("name 'foo' is not defined", "def bar(): a = foo() + 'a'");
  }

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

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

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

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

  // Skylark built-in functions specific tests

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

  @Test
  public void testEmptyLiteralGenericIsSetInLaterConcatWorks() {
    parse("def func():", "  s = {}", "  s['a'] = 'b'\n");
  }

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

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

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

  @Test
  public void testFunctionReturnsFunction() {
    parse(
        "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() {
    parse("len([1, 2]) == 0 and True");
    parse("len([1, 2]) == 0 and False");
  }

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

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

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

  @Test
  public void testKeywordArgAfterStarArg() throws Exception {
    checkError(
        "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 {
    setFailFast(false);
    parseFile("for i in []: 0\n");
    assertContainsError("for loops are not allowed at the top level");
  }

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

  private void parse(String... lines) {
    parseFile(lines);
    events.assertNoWarningsOrErrors();
  }

  private void checkError(String errorMsg, String... lines) {
    setFailFast(false);
    parseFile(lines);
    assertContainsError(errorMsg);
  }
}
