// Copyright 2014 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.syntax.util.EvaluationTestCase;
import com.google.devtools.build.lib.testutil.MoreAsserts;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * A test class for functions and scoping.
 */
@RunWith(JUnit4.class)
public class FunctionTest extends EvaluationTestCase {

  @Test
  public void testFunctionDef() throws Exception {
    exec(
        "def func(a,b,c):", //
        "  a = 1",
        "  b = a\n");
    StarlarkFunction stmt = (StarlarkFunction) lookup("func");
    assertThat(stmt).isNotNull();
    assertThat(stmt.getName()).isEqualTo("func");
    assertThat(stmt.getSignature().numMandatoryPositionals()).isEqualTo(3);
    assertThat(stmt.getStatements()).hasSize(2);
  }

  @Test
  public void testFunctionDefDuplicateArguments() throws Exception {
    // TODO(adonovan): move to ParserTest.
    ParserInput input =
        ParserInput.fromLines(
            "def func(a,b,a):", //
            "  a = 1\n");
    StarlarkFile file = StarlarkFile.parse(input);
    MoreAsserts.assertContainsEvent(
        file.errors(), "duplicate parameter name in function definition");
  }

  @Test
  public void testFunctionDefCallOuterFunc() throws Exception {
    List<Object> params = new ArrayList<>();
    createOuterFunction(params);
    exec(
        "def func(a):", //
        "  outer_func(a)",
        "func(1)",
        "func(2)");
    assertThat(params).containsExactly(1, 2).inOrder();
  }

  private void createOuterFunction(final List<Object> params) throws Exception {
    BaseFunction outerFunc =
        new BaseFunction("outer_func") {
          @Override
          public Object call(
              List<Object> args,
              Map<String, Object> kwargs,
              FuncallExpression ast,
              StarlarkThread thread)
              throws EvalException, InterruptedException {
            params.addAll(args);
            return Runtime.NONE;
          }
        };
    update("outer_func", outerFunc);
  }

  @Test
  public void testFunctionDefNoEffectOutsideScope() throws Exception {
    update("a", 1);
    exec(
        "def func():", //
        "  a = 2",
        "func()\n");
    assertThat(lookup("a")).isEqualTo(1);
  }

  @Test
  public void testFunctionDefGlobalVaribleReadInFunction() throws Exception {
    exec(
        "a = 1", //
        "def func():",
        "  b = a",
        "  return b",
        "c = func()\n");
    assertThat(lookup("c")).isEqualTo(1);
  }

  @Test
  public void testFunctionDefLocalGlobalScope() throws Exception {
    exec(
        "a = 1", //
        "def func():",
        "  a = 2",
        "  b = a",
        "  return b",
        "c = func()\n");
    assertThat(lookup("c")).isEqualTo(2);
  }

  @Test
  public void testFunctionDefLocalVariableReferencedBeforeAssignment() throws Exception {
    checkEvalErrorContains(
        "local variable 'a' is referenced before assignment.",
        "a = 1",
        "def func():",
        "  b = a",
        "  a = 2",
        "  return b",
        "c = func()\n");
  }

  @Test
  public void testFunctionDefLocalVariableReferencedInCallBeforeAssignment() throws Exception {
    checkEvalErrorContains(
        "local variable 'a' is referenced before assignment.",
        "def dummy(x):",
        "  pass",
        "a = 1",
        "def func():",
        "  dummy(a)",
        "  a = 2",
        "func()\n");
  }

  @Test
  public void testFunctionDefLocalVariableReferencedAfterAssignment() throws Exception {
    exec(
        "a = 1", //
        "def func():",
        "  a = 2",
        "  b = a",
        "  a = 3",
        "  return b",
        "c = func()\n");
    assertThat(lookup("c")).isEqualTo(2);
  }

  @SuppressWarnings("unchecked")
  @Test
  public void testSkylarkGlobalComprehensionIsAllowed() throws Exception {
    exec("a = [i for i in [1, 2, 3]]\n");
    assertThat((Iterable<Object>) lookup("a")).containsExactly(1, 2, 3).inOrder();
  }

  @Test
  public void testFunctionReturn() throws Exception {
    exec(
        "def func():", //
        "  return 2",
        "b = func()\n");
    assertThat(lookup("b")).isEqualTo(2);
  }

  @Test
  public void testFunctionReturnFromALoop() throws Exception {
    exec(
        "def func():", //
        "  for i in [1, 2, 3, 4, 5]:",
        "    return i",
        "b = func()\n");
    assertThat(lookup("b")).isEqualTo(1);
  }

  @Test
  public void testFunctionExecutesProperly() throws Exception {
    exec(
        "def func(a):",
        "  b = 1",
        "  if a:",
        "    b = 2",
        "  return b",
        "c = func(0)",
        "d = func(1)\n");
    assertThat(lookup("c")).isEqualTo(1);
    assertThat(lookup("d")).isEqualTo(2);
  }

  @Test
  public void testFunctionCallFromFunction() throws Exception {
    final List<Object> params = new ArrayList<>();
    createOuterFunction(params);
    exec(
        "def func2(a):",
        "  outer_func(a)",
        "def func1(b):",
        "  func2(b)",
        "func1(1)",
        "func1(2)\n");
    assertThat(params).containsExactly(1, 2).inOrder();
  }

  @Test
  public void testFunctionCallFromFunctionReadGlobalVar() throws Exception {
    exec(
        "a = 1", //
        "def func2():",
        "  return a",
        "def func1():",
        "  return func2()",
        "b = func1()\n");
    assertThat(lookup("b")).isEqualTo(1);
  }

  @Test
  public void testFunctionParamCanShadowGlobalVarAfterGlobalVarIsRead() throws Exception {
    exec(
        "a = 1",
        "def func2(a):",
        "  return 0",
        "def func1():",
        "  dummy = a",
        "  return func2(2)",
        "b = func1()\n");
    assertThat(lookup("b")).isEqualTo(0);
  }

  @Test
  public void testSingleLineFunction() throws Exception {
    exec(
        "def func(): return 'a'", //
        "s = func()\n");
    assertThat(lookup("s")).isEqualTo("a");
  }

  @Test
  public void testFunctionReturnsDictionary() throws Exception {
    exec(
        "def func(): return {'a' : 1}", //
        "d = func()",
        "a = d['a']\n");
    assertThat(lookup("a")).isEqualTo(1);
  }

  @Test
  public void testFunctionReturnsList() throws Exception {
    exec(
        "def func(): return [1, 2, 3]", //
        "d = func()",
        "a = d[1]\n");
    assertThat(lookup("a")).isEqualTo(2);
  }

  @Test
  public void testFunctionNameAliasing() throws Exception {
    exec(
        "def func(a):", //
        "  return a + 1",
        "alias = func",
        "r = alias(1)");
    assertThat(lookup("r")).isEqualTo(2);
  }

  @Test
  public void testCallingFunctionsWithMixedModeArgs() throws Exception {
    exec(
        "def func(a, b, c):", //
        "  return a + b + c",
        "v = func(1, c = 2, b = 3)");
    assertThat(lookup("v")).isEqualTo(6);
  }

  private String functionWithOptionalArgs() {
    return "def func(a, b = None, c = None):\n"
        + "  r = a + 'a'\n"
        + "  if b:\n"
        + "    r += 'b'\n"
        + "  if c:\n"
        + "    r += 'c'\n"
        + "  return r\n";
  }

  @Test
  public void testWhichOptionalArgsAreDefinedForFunctions() throws Exception {
    exec(
        functionWithOptionalArgs(),
        "v1 = func('1', 1, 1)",
        "v2 = func(b = 2, a = '2', c = 2)",
        "v3 = func('3')",
        "v4 = func('4', c = 1)\n");
    assertThat(lookup("v1")).isEqualTo("1abc");
    assertThat(lookup("v2")).isEqualTo("2abc");
    assertThat(lookup("v3")).isEqualTo("3a");
    assertThat(lookup("v4")).isEqualTo("4ac");
  }

  @Test
  public void testDefaultArguments() throws Exception {
    exec(
        "def func(a, b = 'b', c = 'c'):",
        "  return a + b + c",
        "v1 = func('a', 'x', 'y')",
        "v2 = func(b = 'x', a = 'a', c = 'y')",
        "v3 = func('a')",
        "v4 = func('a', c = 'y')\n");
    assertThat(lookup("v1")).isEqualTo("axy");
    assertThat(lookup("v2")).isEqualTo("axy");
    assertThat(lookup("v3")).isEqualTo("abc");
    assertThat(lookup("v4")).isEqualTo("aby");
  }

  @Test
  public void testDefaultArgumentsInsufficientArgNum() throws Exception {
    checkEvalError("insufficient arguments received by func(a, b = \"b\", c = \"c\") "
        + "(got 0, expected at least 1)",
        "def func(a, b = 'b', c = 'c'):",
        "  return a + b + c",
        "func()");
  }

  @Test
  public void testArgsIsNotIterable() throws Exception {
    checkEvalError(
        "argument after * must be an iterable, not int",
        "def func1(a, b): return a + b",
        "func1('a', *42)");

    checkEvalError(
        "argument after * must be an iterable, not string",
        "def func2(a, b): return a + b",
        "func2('a', *'str')");
  }

  @Test
  public void testKeywordOnlyIsForbidden() throws Exception {
    checkEvalErrorContains("forbidden", "def foo(a, b, *, c): return a + b + c");
  }

  @Test
  public void testParamAfterStarArgs() throws Exception {
    checkEvalErrorContains("forbidden", "def foo(a, *b, c): return a");
  }

  @Test
  public void testKwargsBadKey() throws Exception {
    checkEvalError(
        "keywords must be strings, not 'int'",
        "def func(a, b): return a + b",
        "func('a', **{3: 1})");
  }

  @Test
  public void testKwargsIsNotDict() throws Exception {
    checkEvalError(
        "argument after ** must be a dictionary, not 'int'",
        "def func(a, b): return a + b",
        "func('a', **42)");
  }

  @Test
  public void testKwargsCollision() throws Exception {
    checkEvalError("argument 'b' passed both by position and by name in call to func(a, b)",
        "def func(a, b): return a + b",
        "func('a', 'b', **{'b': 'foo'})");
  }

  @Test
  public void testKwargsCollisionWithNamed() throws Exception {
    checkEvalError("duplicate keyword 'b' in call to func",
        "def func(a, b): return a + b",
        "func('a', b = 'b', **{'b': 'foo'})");
  }

  @Test
  public void testDefaultArguments2() throws Exception {
    exec(
        "a = 2",
        "def foo(x=a): return x",
        "def bar():",
        "  a = 3",
        "  return foo()",
        "v = bar()\n");
    assertThat(lookup("v")).isEqualTo(2);
  }

  @Test
  public void testMixingPositionalOptional() throws Exception {
    exec(
        "def f(name, value = '', optional = ''):", //
        "  return value",
        "v = f('name', 'value')");
    assertThat(lookup("v")).isEqualTo("value");
  }

  @Test
  public void testStarArg() throws Exception {
    exec(
        "def f(name, value = '1', optional = '2'): return name + value + optional",
        "v1 = f(*['name', 'value'])",
        "v2 = f('0', *['name', 'value'])",
        "v3 = f('0', optional = '3', *['b'])",
        "v4 = f(name='a', *[])\n");
    assertThat(lookup("v1")).isEqualTo("namevalue2");
    assertThat(lookup("v2")).isEqualTo("0namevalue");
    assertThat(lookup("v3")).isEqualTo("0b3");
    assertThat(lookup("v4")).isEqualTo("a12");
  }

  @Test
  public void testStarParam() throws Exception {
    exec(
        "def f(name, value = '1', optional = '2', *rest):",
        "  r = name + value + optional + '|'",
        "  for x in rest: r += x",
        "  return r",
        "v1 = f('a', 'b', 'c', 'd', 'e')",
        "v2 = f('a', optional='b', value='c')",
        "v3 = f('a')");
    assertThat(lookup("v1")).isEqualTo("abc|de");
    assertThat(lookup("v2")).isEqualTo("acb|");
    assertThat(lookup("v3")).isEqualTo("a12|");
  }
}
