// 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.skyframe;

import static com.google.common.truth.Truth.assertThat;

import com.google.common.base.Ascii;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.packages.NoSuchTargetException;
import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.packages.PackageFactory.EnvironmentExtension;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.WorkspaceFileValue;
import com.google.devtools.build.lib.skyframe.util.SkyframeExecutorTestUtils;
import com.google.devtools.build.lib.util.AbruptExitException;
import com.google.devtools.build.lib.vfs.ModifiedFileSet;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.Root;
import com.google.devtools.build.lib.vfs.RootedPath;
import com.google.devtools.build.skyframe.EvaluationResult;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import net.starlark.java.syntax.ParserInput;
import net.starlark.java.syntax.StarlarkFile;
import net.starlark.java.syntax.Statement;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Test for {@link WorkspaceFileFunction}.
 */
@RunWith(JUnit4.class)
public class WorkspaceFileFunctionTest extends BuildViewTestCase {
  @Override
  protected Iterable<EnvironmentExtension> getEnvironmentExtensions() {
    return ImmutableList.of();
  }

  private static Label getLabelMapping(Package pkg, String name) throws NoSuchTargetException {
    return (Label) ((Rule) pkg.getTarget(name)).getAttr("actual");
  }

  private RootedPath createWorkspaceFile(String... contents) throws IOException {
    Path workspacePath = scratch.overwriteFile("WORKSPACE", contents);
    return RootedPath.toRootedPath(
        Root.fromPath(workspacePath.getParentDirectory()),
        PathFragment.create(workspacePath.getBaseName()));
  }

  private <T extends SkyValue> EvaluationResult<T> eval(SkyKey key)
      throws InterruptedException, AbruptExitException {
    getSkyframeExecutor()
        .invalidateFilesUnderPathForTesting(
            reporter,
            ModifiedFileSet.builder().modify(PathFragment.create("WORKSPACE")).build(),
            Root.fromPath(rootDirectory));
    return SkyframeExecutorTestUtils.evaluate(
        getSkyframeExecutor(), key, /*keepGoing=*/ false, reporter);
  }

  @Test
  public void testLoadToChunkMapSimple() throws Exception {
    scratch.file("a.bzl", "a = 'a'");
    scratch.file("b.bzl", "b = 'b'");
    scratch.file("BUILD", "");
    RootedPath workspace =
        createWorkspaceFile(
            "workspace(name = 'good')",
            "load('//:a.bzl', 'a')",
            "x = 1  #for chunk break",
            "load('//:b.bzl', 'b')");
    SkyKey key1 = WorkspaceFileValue.key(workspace, 1);
    EvaluationResult<WorkspaceFileValue> result1 = eval(key1);
    WorkspaceFileValue value1 = result1.get(key1);
    assertThat(value1.getLoadToChunkMap()).containsEntry("//:a.bzl", 1);

    SkyKey key2 = WorkspaceFileValue.key(workspace, 2);
    EvaluationResult<WorkspaceFileValue> result2 = eval(key2);
    WorkspaceFileValue value2 = result2.get(key2);
    assertThat(value2.getLoadToChunkMap()).containsEntry("//:a.bzl", 1);
    assertThat(value2.getLoadToChunkMap()).containsEntry("//:b.bzl", 2);
  }

  @Test
  public void testLoadToChunkMapDoesNotOverrideDuplicate() throws Exception {
    scratch.file("a.bzl", "a = 'a'");
    scratch.file("BUILD", "");
    RootedPath workspace =
        createWorkspaceFile(
            "workspace(name = 'good')",
            "load('//:a.bzl', 'a')",
            "x = 1  #for chunk break",
            "load('//:a.bzl', 'a')");
    SkyKey key1 = WorkspaceFileValue.key(workspace, 1);
    EvaluationResult<WorkspaceFileValue> result1 = eval(key1);
    WorkspaceFileValue value1 = result1.get(key1);
    assertThat(value1.getLoadToChunkMap()).containsEntry("//:a.bzl", 1);

    SkyKey key2 = WorkspaceFileValue.key(workspace, 2);
    EvaluationResult<WorkspaceFileValue> result2 = eval(key2);
    WorkspaceFileValue value2 = result2.get(key2);
    assertThat(value2.getLoadToChunkMap()).containsEntry("//:a.bzl", 1);
    assertThat(value2.getLoadToChunkMap()).doesNotContainEntry("//:a.bzl", 2);
  }

  @Test
  public void testRepositoryMappingInChunks() throws Exception {
    scratch.file("b.bzl", "b = 'b'");
    scratch.file("BUILD", "");
    RootedPath workspace =
        createWorkspaceFile(
            "workspace(name = 'good')",
            "local_repository(name = 'a', path = '../a', repo_mapping = {'@x' : '@y'})",
            "load('//:b.bzl', 'b')",
            "local_repository(name = 'b', path = '../b', repo_mapping = {'@x' : '@y'})");
    RepositoryName a = RepositoryName.create("a");
    RepositoryName b = RepositoryName.create("b");
    RepositoryName y = RepositoryName.create("y");
    RepositoryName main = RepositoryName.create("");

    SkyKey key0 = WorkspaceFileValue.key(workspace, 0);
    EvaluationResult<WorkspaceFileValue> result0 = eval(key0);
    WorkspaceFileValue value0 = result0.get(key0);
    assertThat(value0.getRepositoryMapping())
        .containsEntry(a, ImmutableMap.of("x", y, "good", main));

    SkyKey key1 = WorkspaceFileValue.key(workspace, 1);
    EvaluationResult<WorkspaceFileValue> result1 = eval(key1);
    WorkspaceFileValue value1 = result1.get(key1);
    assertThat(value1.getRepositoryMapping())
        .containsEntry(a, ImmutableMap.of("x", y, "good", main));
    assertThat(value1.getRepositoryMapping())
        .containsEntry(b, ImmutableMap.of("x", y, "good", main));
  }

  @Test
  public void testBzlVisibility() throws Exception {
    setBuildLanguageOptions(
        "--experimental_bzl_visibility=true", "--experimental_bzl_visibility_allowlist=pkg");

    createWorkspaceFile(
        "workspace(name = 'foo')", //
        "load('//pkg:a.bzl', 'a')");
    scratch.file("pkg/BUILD");
    scratch.file(
        "pkg/a.bzl", //
        "visibility('private')");

    reporter.removeHandler(failFastHandler);
    SkyKey key = ExternalPackageFunction.key();
    eval(key);
    // The evaluation result ends up being null, probably due to the test framework swallowing
    // exceptions (similar to b/26382502). So let's just look for the error event instead of
    // asserting on the exception.
    assertContainsEvent(
        "Starlark file //pkg:a.bzl is not visible for loading from package //. Check the file's"
            + " `visibility()` declaration.");
  }

  @Test
  public void testInvalidRepo() throws Exception {
    // Test intentionally introduces errors.
    reporter.removeHandler(failFastHandler);

    createWorkspaceFile("workspace(name = 'foo$')");
    SkyKey key = ExternalPackageFunction.key();
    EvaluationResult<PackageValue> evaluationResult = eval(key);
    Package pkg = evaluationResult.get(key).getPackage();
    assertThat(pkg.containsErrors()).isTrue();
    assertContainsEvent("Error in workspace: invalid user-provided repo name 'foo$'");
  }

  @Test
  public void testBindFunction() throws Exception {
    String[] lines = {"bind(name = 'foo/bar',", "actual = '//foo:bar')"};
    createWorkspaceFile(lines);

    SkyKey key = ExternalPackageFunction.key();
    EvaluationResult<PackageValue> evaluationResult = eval(key);
    Package pkg = evaluationResult.get(key).getPackage();
    assertThat(getLabelMapping(pkg, "foo/bar")).isEqualTo(Label.parseCanonical("//foo:bar"));
    assertNoEvents();
  }

  @Test
  public void testBindArgsReversed() throws Exception {
    String[] lines = {"bind(actual = '//foo:bar', name = 'foo/bar')"};
    createWorkspaceFile(lines);

    SkyKey key = ExternalPackageFunction.key();
    EvaluationResult<PackageValue> evaluationResult = eval(key);
    Package pkg = evaluationResult.get(key).getPackage();
    assertThat(getLabelMapping(pkg, "foo/bar")).isEqualTo(Label.parseCanonical("//foo:bar"));
    assertNoEvents();
  }

  @Test
  public void testNonExternalBinding() throws Exception {
    // Test intentionally introduces errors.
    reporter.removeHandler(failFastHandler);

    // name must be a valid label name.
    String[] lines = {"bind(name = 'foo:bar', actual = '//bar/baz')"};
    createWorkspaceFile(lines);

    SkyKey key = ExternalPackageFunction.key();
    EvaluationResult<PackageValue> evaluationResult = eval(key);
    Package pkg = evaluationResult.get(key).getPackage();
    assertThat(pkg.containsErrors()).isTrue();
    assertContainsEvent("target names may not contain ':'");
  }

  @Test
  public void testWorkspaceFileParsingError() throws Exception {
    // Test intentionally introduces errors.
    reporter.removeHandler(failFastHandler);

    // //external:bar:baz is not a legal package.
    String[] lines = {"bind(name = 'foo/bar', actual = '//external:bar:baz')"};
    createWorkspaceFile(lines);

    SkyKey key = ExternalPackageFunction.key();
    EvaluationResult<PackageValue> evaluationResult = eval(key);
    Package pkg = evaluationResult.get(key).getPackage();
    assertThat(pkg.containsErrors()).isTrue();
    assertContainsEvent("target names may not contain ':'");
  }

  @Test
  public void testRegisterToolchainsInvalidPattern() throws Exception {
    // Test intentionally introduces errors.
    reporter.removeHandler(failFastHandler);

    // //external:bar:baz is not a legal package.
    String[] lines = {"register_toolchains('/:invalid:label:syntax')"};
    createWorkspaceFile(lines);

    SkyKey key = ExternalPackageFunction.key();
    EvaluationResult<PackageValue> evaluationResult = eval(key);
    Package pkg = evaluationResult.get(key).getPackage();
    assertThat(pkg.containsErrors()).isTrue();
    assertContainsEvent("not a valid absolute pattern");
  }

  @Test
  public void testNoWorkspaceFile() throws Exception {
    // Create and immediately delete to make sure we got the right file.
    RootedPath workspacePath = createWorkspaceFile();
    workspacePath.asPath().delete();

    SkyKey key = ExternalPackageFunction.key();
    EvaluationResult<PackageValue> evaluationResult = eval(key);
    Package pkg = evaluationResult.get(key).getPackage();
    assertThat(pkg.containsErrors()).isFalse();
    assertNoEvents();
  }

  @Test
  public void testListBindFunction() throws Exception {
    String[] lines = {
      "L = ['foo', 'bar']", "bind(name = '%s/%s' % (L[0], L[1]),", "actual = '//foo:bar')"
    };
    createWorkspaceFile(lines);

    SkyKey key = ExternalPackageFunction.key();
    EvaluationResult<PackageValue> evaluationResult = eval(key);
    Package pkg = evaluationResult.get(key).getPackage();
    assertThat(getLabelMapping(pkg, "foo/bar")).isEqualTo(Label.parseCanonical("//foo:bar"));
    assertNoEvents();
  }

  @Test
  public void testMangledExternalWorkspaceFileIsIgnored() throws Exception {
    scratch.file("secondary/WORKSPACE", "garbage");
    RootedPath workspace =
        createWorkspaceFile(
            "workspace(name = 'good')",
            "local_repository(name = \"secondary\", path = \"./secondary/\")");

    SkyKey key1 = WorkspaceFileValue.key(workspace, 1);
    EvaluationResult<WorkspaceFileValue> result1 = eval(key1);
    WorkspaceFileValue value1 = result1.get(key1);
    RepositoryName main = RepositoryName.create("");
    RepositoryName secondary = RepositoryName.create("secondary");
    assertThat(value1.getRepositoryMapping())
        .containsEntry(secondary, ImmutableMap.of("good", main));
    assertNoEvents();
  }
  // tests of splitChunks, an internal helper function

  @Test
  public void testChunksNoLoad() {
    assertThat(split(parse("foo_bar = 1"))).isEqualTo("[(assignment)]");
  }

  @Test
  public void testChunksOneLoadAtTop() {
    assertThat(
            split(
                parse(
                    "load('//:foo.bzl', 'bar')", //
                    "foo_bar = 1")))
        .isEqualTo("[(load assignment)]");
  }

  @Test
  public void testChunksOneLoad() {
    assertThat(
            split(
                parse(
                    "foo_bar = 1",
                    //
                    "load('//:foo.bzl', 'bar')")))
        .isEqualTo("[(assignment)][(load)]");
  }

  @Test
  public void testChunksTwoSuccessiveLoads() {
    assertThat(
            split(
                parse(
                    "foo_bar = 1",
                    //
                    "load('//:foo.bzl', 'bar')",
                    "load('//:bar.bzl', 'foo')")))
        .isEqualTo("[(assignment)][(load load)]");
  }

  @Test
  public void testChunksTwoSucessiveLoadsWithNonLoadStatement() {
    assertThat(
            split(
                parse(
                    "foo_bar = 1",
                    //
                    "load('//:foo.bzl', 'bar')",
                    "load('//:bar.bzl', 'foo')",
                    "local_repository(name = 'foobar', path = '/bar/foo')")))
        .isEqualTo("[(assignment)][(load load expression)]");
  }

  @Test
  public void testChunksThreeLoadsThreeSegments() {
    assertThat(
            split(
                parse(
                    "foo_bar = 1",
                    //
                    "load('//:foo.bzl', 'bar')",
                    "load('//:bar.bzl', 'foo')",
                    "local_repository(name = 'foobar', path = '/bar/foo')",
                    //
                    "load('@foobar//:baz.bzl', 'bleh')")))
        .isEqualTo("[(assignment)][(load load expression)][(load)]");
  }

  @Test
  public void testChunksThreeLoadsThreeSegmentsWithContent() {
    assertThat(
            split(
                parse(
                    "foo_bar = 1",
                    //
                    "load('//:foo.bzl', 'bar')",
                    "load('//:bar.bzl', 'foo')",
                    "local_repository(name = 'foobar', path = '/bar/foo')",
                    //
                    "load('@foobar//:baz.bzl', 'bleh')",
                    "bleh()")))
        .isEqualTo("[(assignment)][(load load expression)][(load expression)]");
  }

  @Test
  public void testChunksMaySpanFiles() {
    assertThat(
            split(
                parse(
                    "x = 1", //
                    "load('m', 'y')"),
                parse(
                    "z = 1", //
                    "load('m', 'y2')")))
        .isEqualTo("[(assignment)][(load)(assignment)][(load)]");
  }

  // Returns a string that indicates the breakdown of statements into chunks.
  private static String split(StarlarkFile... files) {
    StringBuilder buf = new StringBuilder();
    for (List<StarlarkFile> chunk : WorkspaceFileFunction.splitChunks(Arrays.asList(files))) {
      buf.append('[');
      for (StarlarkFile partialFile : chunk) {
        buf.append('(');
        String sep = "";
        for (Statement stmt : partialFile.getStatements()) {
          buf.append(sep).append(Ascii.toLowerCase(stmt.kind().toString()));
          sep = " ";
        }
        buf.append(')');
      }
      buf.append(']');
    }
    return buf.toString();
  }

  private static StarlarkFile parse(String... lines) {
    return StarlarkFile.parse(ParserInput.fromLines(lines));
  }
}
