// Copyright 2016 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.collect.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.assertThat;

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.PackageIdentifier;
import com.google.devtools.build.lib.packages.NoSuchPackageException;
import com.google.devtools.build.lib.skyframe.util.SkyframeExecutorTestUtils;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.vfs.DigestHashFunction;
import com.google.devtools.build.lib.vfs.FileStatus;
import com.google.devtools.build.lib.vfs.FileSystem;
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.inmemoryfs.InMemoryFileSystem;
import com.google.devtools.build.skyframe.ErrorInfo;
import com.google.devtools.build.skyframe.EvaluationResult;
import com.google.devtools.build.skyframe.SkyKey;
import java.io.IOException;
import java.math.BigInteger;
import java.util.List;
import net.starlark.java.eval.Module;
import net.starlark.java.eval.Mutability;
import net.starlark.java.eval.Starlark;
import net.starlark.java.eval.StarlarkSemantics;
import net.starlark.java.eval.StarlarkThread;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Unit tests of specific functionality of BzlCompileFunction. */
@RunWith(JUnit4.class)
public class BzlCompileFunctionTest extends BuildViewTestCase {

  private static class MockFileSystem extends InMemoryFileSystem {
    PathFragment throwIOExceptionFor = null;

    MockFileSystem() {
      super(DigestHashFunction.SHA256);
    }

    @Override
    public FileStatus statIfFound(PathFragment path, boolean followSymlinks) throws IOException {
      if (path.equals(throwIOExceptionFor)) {
        throw new IOException("bork");
      }
      return super.statIfFound(path, followSymlinks);
    }
  }

  private MockFileSystem mockFS;

  @Override
  protected FileSystem createFileSystem() {
    mockFS = new MockFileSystem();
    return mockFS;
  }

  @Test
  public void testIOExceptionOccursDuringReading() throws Exception {
    reporter.removeHandler(failFastHandler);
    scratch.file("/workspace/tools/build_rules/BUILD");
    scratch.file(
        "foo/BUILD", //
        "genrule(",
        "    name = 'foo',",
        "    outs = ['out.txt'],",
        "    cmd = 'echo hello >@'",
        ")");
    mockFS.throwIOExceptionFor = PathFragment.create("/workspace/foo/BUILD");
    invalidatePackages(/*alsoConfigs=*/ false); // We don't want to fail early on config creation.

    SkyKey skyKey = PackageIdentifier.createInMainRepo("foo");
    EvaluationResult<PackageValue> result =
        SkyframeExecutorTestUtils.evaluate(
            getSkyframeExecutor(), skyKey, /*keepGoing=*/ false, reporter);
    assertThat(result.hasError()).isTrue();
    ErrorInfo errorInfo = result.getError(skyKey);
    Throwable e = errorInfo.getException();
    assertThat(e).isInstanceOf(NoSuchPackageException.class);
    assertThat(e).hasMessageThat().contains("bork");
  }

  @Test
  public void testLoadFromFileInRemoteRepo() throws Exception {
    scratch.overwriteFile(
        "WORKSPACE",
        "local_repository(",
        "    name = 'a_remote_repo',",
        "    path = '/a_remote_repo'",
        ")");
    Path repoPath = scratch.dir("/a_remote_repo");
    scratch.file("/a_remote_repo/WORKSPACE");
    scratch.file("/a_remote_repo/remote_pkg/BUILD");
    scratch.file("/a_remote_repo/remote_pkg/foo.bzl", "load(':bar.bzl', 'CONST')");
    scratch.file("/a_remote_repo/remote_pkg/bar.bzl", "CONST = 17");

    invalidatePackages(/*alsoConfigs=*/ false); // Repository shuffling messes with toolchains.
    SkyKey skyKey =
        BzlCompileValue.key(
            Root.fromPath(repoPath),
            Label.parseCanonicalUnchecked("@a_remote_repo//remote_pkg:foo.bzl"));
    EvaluationResult<BzlCompileValue> result =
        SkyframeExecutorTestUtils.evaluate(
            getSkyframeExecutor(), skyKey, /* keepGoing= */ false, reporter);
    List<String> loads =
        BzlLoadFunction.getLoadsFromProgram(result.get(skyKey).getProgram()).stream()
            .map(Pair::getFirst)
            .collect(toImmutableList());
    assertThat(loads).containsExactly(":bar.bzl");
  }

  @Test
  public void testLoadOfNonexistentFile() throws Exception {
    SkyKey skyKey = BzlCompileValue.key(root, Label.parseCanonicalUnchecked("//pkg:foo.bzl"));
    EvaluationResult<BzlCompileValue> result =
        SkyframeExecutorTestUtils.evaluate(
            getSkyframeExecutor(), skyKey, /* keepGoing= */ false, reporter);
    assertThat(result.get(skyKey).lookupSuccessful()).isFalse();
    assertThat(result.get(skyKey).getError()).contains("cannot load '//pkg:foo.bzl': no such file");
  }

  @Test
  public void testBigIntegerLiterals() throws Exception {
    // This test ensures that numerical literals with values that can't be expressed as Java longs
    // can be compiled. Regression test for b/217548647.
    SkyKey skyKey = BzlCompileValue.key(root, Label.parseCanonicalUnchecked("//pkg:bigint.bzl"));
    scratch.file("pkg/BUILD");
    scratch.file(
        "pkg/bigint.bzl",
        String.format(
            "[%s, %s]",
            BigInteger.valueOf(Long.MIN_VALUE).subtract(BigInteger.ONE),
            BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE)));

    EvaluationResult<BzlCompileValue> result =
        SkyframeExecutorTestUtils.evaluate(
            getSkyframeExecutor(), skyKey, /*keepGoing=*/ false, reporter);
    BzlCompileValue bzlCompileValue = result.get(skyKey);
    assertThat(bzlCompileValue.lookupSuccessful()).isTrue();

    try (Mutability mu = Mutability.create()) {
      Object val =
          Starlark.execFileProgram(
              bzlCompileValue.getProgram(),
              Module.withPredeclared(StarlarkSemantics.DEFAULT, ImmutableMap.of()),
              new StarlarkThread(mu, StarlarkSemantics.DEFAULT));
      assertThat(val.toString()).isEqualTo("[-9223372036854775809, 9223372036854775808]");
    }
  }
}
