// Copyright 2019 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.blackbox.tests.workspace;

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

import com.google.devtools.build.lib.bazel.repository.DecompressorDescriptor;
import com.google.devtools.build.lib.bazel.repository.TarFunction;
import com.google.devtools.build.lib.blackbox.framework.BuilderRunner;
import com.google.devtools.build.lib.blackbox.framework.PathUtils;
import com.google.devtools.build.lib.blackbox.junit.AbstractBlackBoxTest;
import com.google.devtools.build.lib.rules.repository.RepositoryFunction.RepositoryFunctionException;
import com.google.devtools.build.lib.vfs.FileSystem;
import com.google.devtools.build.lib.vfs.util.FileSystems;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import org.junit.Test;

/**
 * Test that the embedded Starlark code is compliant with --all_incompatible_changes. To replace
 * bazel_embedded_skylark_test.sh.
 */
public class BazelEmbeddedSkylarkBlackBoxTest extends AbstractBlackBoxTest {

  private static final String HELLO_FROM_EXTERNAL_REPOSITORY = "Hello from external repository!";
  private static final String HELLO_FROM_MAIN_REPOSITORY = "Hello from main repository!";

  @Test
  public void testPkgTar() throws Exception {
    context().write("main/WORKSPACE");
    context().write("main/foo.txt", "Hello World");
    context().write("main/bar.txt", "Hello World, again");
    context()
        .write(
            "main/BUILD",
            "load(\"@bazel_tools//tools/build_defs/pkg:pkg.bzl\", \"pkg_tar\")",
            "pkg_tar(name = \"data\", srcs = ['foo.txt', 'bar.txt'],)");

    BuilderRunner bazel = bazel();
    bazel.build("...");

    Path dataTarPath = context().resolveBinPath(bazel, "main/data.tar");
    assertThat(Files.exists(dataTarPath)).isTrue();

    Path directory = decompress(dataTarPath);
    assertThat(directory.toFile().exists()).isTrue();

    Map<String, Path> map =
        Arrays.stream(Objects.requireNonNull(directory.toFile().listFiles()))
            .collect(Collectors.toMap(File::getName, file -> Paths.get(file.getAbsolutePath())));

    WorkspaceTestUtils.assertLinesExactly(map.get("foo.txt"), "Hello World");
    WorkspaceTestUtils.assertLinesExactly(map.get("bar.txt"), "Hello World, again");
  }

  @Test
  public void testHttpArchive() throws Exception {
    Path repo = context().getTmpDir().resolve("ext_repo");
    RepoWithRuleWritingTextGenerator generator = new RepoWithRuleWritingTextGenerator(repo);
    generator.withOutputText(HELLO_FROM_EXTERNAL_REPOSITORY).setupRepository();

    // file where we will manually copy the built archive
    Path zipFile = context().getTmpDir().resolve("ext_repo.tar");
    assertThat(Files.exists(zipFile)).isFalse();

    context()
        .write(
            "WORKSPACE",
            "load(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\n",
            String.format(
                "local_repository(name=\"ext_local\", path=\"%s\",)",
                PathUtils.pathForStarlarkFile(repo)),
            String.format(
                "http_archive(name=\"ext\", urls=[\"%s\"],)", PathUtils.pathToFileURI(zipFile)));

    context()
        .write(
            "BUILD",
            RepoWithRuleWritingTextGenerator.loadRule("@ext"),
            RepoWithRuleWritingTextGenerator.callRule(
                "call_from_main", "main_out.txt", HELLO_FROM_MAIN_REPOSITORY));

    // first build the archive and copy it into zipFile
    BuilderRunner bazel = bazel();
    String tarTarget = generator.getPkgTarTarget();
    bazel.build("@ext_local//:" + tarTarget);
    Path packedFile =
        context().resolveBinPath(bazel, String.format("external/ext_local/%s.tar", tarTarget));
    Files.copy(packedFile, zipFile);

    // now build the target from http_archive
    bazel.build("@ext//:" + RepoWithRuleWritingTextGenerator.TARGET);

    Path xPath = context().resolveBinPath(bazel, "external/ext/out");
    WorkspaceTestUtils.assertLinesExactly(xPath, HELLO_FROM_EXTERNAL_REPOSITORY);

    // and use the rule from http_archive in the main repository
    bazel.build("//:call_from_main");

    Path mainOutPath = context().resolveBinPath(bazel, "main_out.txt");
    WorkspaceTestUtils.assertLinesExactly(mainOutPath, HELLO_FROM_MAIN_REPOSITORY);
  }

  private BuilderRunner bazel() {
    // On Mac, set host config to use PY2 because our CI Mac workers don't have a Python 3 runtime.
    // TODO(https://github.com/bazelbuild/continuous-integration/issues/578): Remove this
    // workaround.
    if (System.getProperty("os.name").toLowerCase().startsWith("mac os x")) {
      System.out.println(
          "Setting host Python to PY2 to workaround unavailability of Python 3 on Mac CI");
      return WorkspaceTestUtils.bazel(context())
          .withFlags("--all_incompatible_changes", "--host_force_python=PY2");
    } else {
      return WorkspaceTestUtils.bazel(context()).withFlags("--all_incompatible_changes");
    }
  }

  private Path decompress(Path dataTarPath) throws IOException, RepositoryFunctionException {
    FileSystem fs = FileSystems.getNativeFileSystem();
    com.google.devtools.build.lib.vfs.Path dataTarPathForDecompress =
        fs.getPath(dataTarPath.toAbsolutePath().toString());

    com.google.devtools.build.lib.vfs.Path directory =
        TarFunction.INSTANCE.decompress(
            DecompressorDescriptor.builder()
                .setArchivePath(dataTarPathForDecompress)
                .setRepositoryPath(dataTarPathForDecompress.getParentDirectory())
                .build());
    return Paths.get(directory.getPathString());
  }

  // TODO(ichern) test tar quoting
}
