// 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.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.packages.Info;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.syntax.util.EvaluationTestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Tests for the validation process of Skylark files.
 */
@RunWith(JUnit4.class)
public class ValidationTest extends EvaluationTestCase {

  @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 {
    env = newEnvironmentWithSkylarkOptions("--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 {
    env =
        newEnvironmentWithSkylarkOptions("--incompatible_bzl_disallow_load_after_statement=false");
    parse("a = 5", "load(':b.bzl', 'c')");
  }

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

  @Test
  public void testAllowedToplevelIfStatement() throws Exception {
    env = newEnvironmentWithSkylarkOptions("--incompatible_disallow_toplevel_if_statement=false");
    parse("if True: a = 5");
  }

  @Test
  public void testTwoFunctionsWithTheSameName() throws Exception {
    checkError(
        "Variable foo is read only", "def foo():", "  return 1", "def foo(x, y):", "  return 1");
  }

  @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 {
    checkError("name 'a' is not defined", "a = a");
    checkError("name 'a' is not defined", "a += a");
    checkError("name 'a' is not defined", "[[] for a in a]");
    checkError("name 'a' is not defined", "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 testBuiltinSymbolsAreReadOnly() throws Exception {
    checkError("Variable repr is read only", "repr = 1");
  }

  @Test
  public void testSkylarkGlobalVariablesAreReadonly() throws Exception {
    checkError("Variable a is read only", "a = 1", "a = 2");
  }

  @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 testFunctionDoesNotExist() {
    checkError("name 'foo' is not defined", "def bar(): a = foo() + 'a'");
  }

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

  @Test
  public void testDictLiteralDifferentValueTypeWorks() 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 : getEventCollector()) {
      assertThat(event.getMessage()).doesNotContain("$error$");
    }
  }

  @Test
  public void testGetSkylarkType() throws Exception {
    Class<?> emptyTupleClass = Tuple.empty().getClass();
    Class<?> tupleClass = Tuple.of(1, "a", "b").getClass();
    Class<?> mutableListClass = MutableList.copyOf(env, Tuple.of(1, 2, 3)).getClass();

    assertThat(EvalUtils.getSkylarkType(mutableListClass)).isEqualTo(MutableList.class);
    assertThat(MutableList.class.isAnnotationPresent(SkylarkModule.class)).isTrue();
    assertThat(EvalUtils.getSkylarkType(emptyTupleClass)).isEqualTo(Tuple.class);
    assertThat(EvalUtils.getSkylarkType(tupleClass)).isEqualTo(Tuple.class);

    assertThat(EvalUtils.getSkylarkType(Info.class)).isEqualTo(Info.class);
    try {
      EvalUtils.getSkylarkType(ClassObject.class);
      throw new Exception("Should have raised IllegalArgumentException exception");
    } catch (IllegalArgumentException e) {
      assertThat(e)
          .hasMessageThat()
          .contains(
              "interface com.google.devtools.build.lib.syntax.ClassObject is not allowed "
                  + "as a Skylark value");
    }
  }

  @Test
  public void testSkylarkTypeEquivalence() throws Exception {
    Class<?> emptyTupleClass = Tuple.empty().getClass();
    Class<?> tupleClass = Tuple.of(1, "a", "b").getClass();
    Class<?> mutableListClass = MutableList.copyOf(env, Tuple.of(1, 2, 3)).getClass();

    assertThat(SkylarkType.of(mutableListClass)).isEqualTo(SkylarkType.LIST);
    assertThat(SkylarkType.of(emptyTupleClass)).isEqualTo(SkylarkType.TUPLE);
    assertThat(SkylarkType.of(tupleClass)).isEqualTo(SkylarkType.TUPLE);
    assertThat(SkylarkType.TUPLE).isNotEqualTo(SkylarkType.LIST);

    try {
      SkylarkType.of(ClassObject.class);
      throw new Exception("foo");
    } catch (Exception e) {
      assertThat(e)
          .hasMessageThat()
          .contains(
              "interface com.google.devtools.build.lib.syntax.ClassObject "
                  + "is not allowed as a Skylark value");
    }

    // Also test for these bazel classes, to avoid some regression.
    // TODO(bazel-team): move to some other place to remove dependency of syntax tests on Artifact?
    assertThat(SkylarkType.of(Artifact.SpecialArtifact.class))
        .isEqualTo(SkylarkType.of(Artifact.class));
    assertThat(SkylarkType.of(RuleConfiguredTarget.class)).isNotEqualTo(SkylarkType.of(Info.class));
  }

  @Test
  public void testSkylarkTypeInclusion() throws Exception {
    assertThat(SkylarkType.INT.includes(SkylarkType.BOTTOM)).isTrue();
    assertThat(SkylarkType.BOTTOM.includes(SkylarkType.INT)).isFalse();
    assertThat(SkylarkType.TOP.includes(SkylarkType.INT)).isTrue();

    SkylarkType combo1 = SkylarkType.Combination.of(SkylarkType.LIST, SkylarkType.INT);
    assertThat(SkylarkType.LIST.includes(combo1)).isTrue();

    SkylarkType union1 =
        SkylarkType.Union.of(SkylarkType.DICT, SkylarkType.LIST);
    assertThat(union1.includes(SkylarkType.DICT)).isTrue();
    assertThat(union1.includes(combo1)).isTrue();
    assertThat(union1.includes(SkylarkType.STRING)).isFalse();

    SkylarkType union2 =
        SkylarkType.Union.of(
            SkylarkType.LIST, SkylarkType.DICT, SkylarkType.STRING, SkylarkType.INT);
    SkylarkType inter1 = SkylarkType.intersection(union1, union2);
    assertThat(inter1.includes(SkylarkType.DICT)).isTrue();
    assertThat(inter1.includes(SkylarkType.LIST)).isTrue();
    assertThat(inter1.includes(combo1)).isTrue();
    assertThat(inter1.includes(SkylarkType.INT)).isFalse();
  }

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

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