// Copyright 2006 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 org.junit.Assert.assertThrows;

import com.google.devtools.build.lib.syntax.util.EvaluationTestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests of StarlarkThread. */
@RunWith(JUnit4.class)
public final class StarlarkThreadTest {

  private final EvaluationTestCase ev = new EvaluationTestCase();

  // Test the API directly
  @Test
  public void testLookupAndUpdate() throws Exception {
    assertThat(ev.lookup("foo")).isNull();
    ev.update("foo", "bar");
    assertThat(ev.lookup("foo")).isEqualTo("bar");
  }

  @Test
  public void testDoubleUpdateSucceeds() throws Exception {
    assertThat(ev.lookup("VERSION")).isNull();
    ev.update("VERSION", 42);
    assertThat(ev.lookup("VERSION")).isEqualTo(42);
    ev.update("VERSION", 43);
    assertThat(ev.lookup("VERSION")).isEqualTo(43);
  }

  // Test assign through interpreter, ev.lookup through API:
  @Test
  public void testAssign() throws Exception {
    assertThat(ev.lookup("foo")).isNull();
    ev.exec("foo = 'bar'");
    assertThat(ev.lookup("foo")).isEqualTo("bar");
  }

  // Test update through API, reference through interpreter:
  @Test
  public void testReference() throws Exception {
    ev.setFailFast(false);
    SyntaxError.Exception e = assertThrows(SyntaxError.Exception.class, () -> ev.eval("foo"));
    assertThat(e).hasMessageThat().isEqualTo("name 'foo' is not defined");
    ev.update("foo", "bar");
    assertThat(ev.eval("foo")).isEqualTo("bar");
  }

  // Test assign and reference through interpreter:
  @Test
  public void testAssignAndReference() throws Exception {
    SyntaxError.Exception e = assertThrows(SyntaxError.Exception.class, () -> ev.eval("foo"));
    assertThat(e).hasMessageThat().isEqualTo("name 'foo' is not defined");
    ev.exec("foo = 'bar'");
    assertThat(ev.eval("foo")).isEqualTo("bar");
  }

  @Test
  public void testBindToNullThrowsException() throws Exception {
    NullPointerException e =
        assertThrows(NullPointerException.class, () -> ev.update("some_name", null));
    assertThat(e).hasMessageThat().isEqualTo("Module.setGlobal(some_name, null)");
  }

  @Test
  public void testBuiltinsCanBeShadowed() throws Exception {
    Module module = Module.create();
    try (Mutability mu = Mutability.create("test")) {
      StarlarkThread thread = new StarlarkThread(mu, StarlarkSemantics.DEFAULT);
      EvalUtils.exec(ParserInput.fromLines("True = 123"), FileOptions.DEFAULT, module, thread);
    }
    assertThat(module.getGlobal("True")).isEqualTo(123);
  }

  @Test
  public void testVariableIsReferencedBeforeAssignment() throws Exception {
    ev.new Scenario()
        .testIfErrorContains(
            "local variable 'y' is referenced before assignment",
            "y = 1", // bind => y is global
            "def foo(x):",
            "  x += y", // fwd ref to local y
            "  y = 2", // binding => y is local
            "  return x",
            "foo(1)");
    ev.new Scenario()
        .testIfErrorContains(
            "global variable 'len' is referenced before assignment",
            "print(len)", // fwd ref to global len
            "len = 1"); // binding => len is local
  }
}
