// Copyright 2018 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.sandbox;

import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.sandbox.SandboxHelpers.SandboxInputs;
import com.google.devtools.build.lib.sandbox.SandboxHelpers.SandboxOutputs;
import com.google.devtools.build.lib.testutil.TestUtils;
import com.google.devtools.build.lib.vfs.FileSystem;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.Symlinks;
import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem;
import java.io.IOException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@link SandboxfsSandboxedSpawn}. */
@RunWith(JUnit4.class)
public class SandboxfsSandboxedSpawnTest {
  private Path testRoot;
  private Path workspaceDir;
  private Path outerDir;
  private SandboxfsProcess sandboxfs;

  @Before
  public final void setupTestDirs() throws IOException {
    FileSystem fileSystem = new InMemoryFileSystem();
    testRoot = fileSystem.getPath(TestUtils.tmpDir());
    testRoot.createDirectoryAndParents();

    workspaceDir = testRoot.getRelative("workspace");
    workspaceDir.createDirectory();
    outerDir = testRoot.getRelative("scratch");
    outerDir.createDirectory();

    Path mountPoint = testRoot.getRelative("sandbox");
    mountPoint.createDirectory();
    sandboxfs = new FakeSandboxfsProcess(
        mountPoint.getFileSystem(), mountPoint.asFragment());
    }

  @Test
  public void testCreateFileSystem() throws Exception {
    Path helloTxt = workspaceDir.getRelative("hello.txt");
    FileSystemUtils.createEmptyFile(helloTxt);

    SandboxedSpawn spawn =
        new SandboxfsSandboxedSpawn(
            sandboxfs,
            outerDir,
            "workspace",
            ImmutableList.of("/bin/true"),
            ImmutableMap.of(),
            new SandboxInputs(
                ImmutableMap.of(PathFragment.create("such/input.txt"), helloTxt),
                ImmutableSet.of(),
                ImmutableMap.of()),
            SandboxOutputs.create(
                ImmutableSet.of(PathFragment.create("very/output.txt")), ImmutableSet.of()),
            ImmutableSet.of(PathFragment.create("wow/writable")),
            /* mapSymlinkTargets= */ false,
            new SynchronousTreeDeleter(),
            /* statisticsPath= */ null);

    spawn.createFileSystem();
    Path execRoot = spawn.getSandboxExecRoot();

    assertThat(execRoot.getRelative("such/input.txt").isSymbolicLink()).isTrue();
    assertThat(execRoot.getRelative("such/input.txt").resolveSymbolicLinks()).isEqualTo(helloTxt);
    assertThat(execRoot.getRelative("very").isDirectory()).isTrue();
    assertThat(execRoot.getRelative("wow/writable").isDirectory()).isTrue();
  }

  @Test
  public void testExecRootContainsWorkspaceName() throws Exception {
    Path helloTxt = workspaceDir.getRelative("hello.txt");
    FileSystemUtils.createEmptyFile(helloTxt);

    SandboxedSpawn spawn =
        new SandboxfsSandboxedSpawn(
            sandboxfs,
            outerDir,
            "some-workspace-name",
            ImmutableList.of("/bin/true"),
            ImmutableMap.of(),
            new SandboxInputs(ImmutableMap.of(), ImmutableSet.of(), ImmutableMap.of()),
            SandboxOutputs.create(ImmutableSet.of(), ImmutableSet.of()),
            ImmutableSet.of(),
            /* mapSymlinkTargets= */ false,
            new SynchronousTreeDeleter(),
            /* statisticsPath= */ null);
    spawn.createFileSystem();
    Path execRoot = spawn.getSandboxExecRoot();

    assertThat(execRoot.getPathString()).contains("/some-workspace-name");
  }

  @Test
  public void testDelete() throws Exception {
    Path helloTxt = workspaceDir.getRelative("hello.txt");
    FileSystemUtils.createEmptyFile(helloTxt);

    SandboxedSpawn spawn =
        new SandboxfsSandboxedSpawn(
            sandboxfs,
            outerDir,
            "workspace",
            ImmutableList.of("/bin/true"),
            ImmutableMap.of(),
            new SandboxInputs(
                ImmutableMap.of(PathFragment.create("such/input.txt"), helloTxt),
                ImmutableSet.of(),
                ImmutableMap.of()),
            SandboxOutputs.create(
                ImmutableSet.of(PathFragment.create("very/output.txt")), ImmutableSet.of()),
            ImmutableSet.of(PathFragment.create("wow/writable")),
            /* mapSymlinkTargets= */ false,
            new SynchronousTreeDeleter(),
            /* statisticsPath= */ null);
    spawn.createFileSystem();
    Path execRoot = spawn.getSandboxExecRoot();

    // Pretend to do some work inside the execRoot.
    execRoot.getRelative("tempdir").createDirectory();
    FileSystemUtils.createEmptyFile(execRoot.getRelative("very/output.txt"));
    FileSystemUtils.createEmptyFile(execRoot.getRelative("wow/writable/temp.txt"));

    spawn.delete();

    assertThat(execRoot.exists()).isFalse();
  }

  @Test
  public void testCopyOutputs() throws Exception {
    // These tests are very simple because we just rely on
    // AbstractContainerizingSandboxedSpawnTest.testMoveOutputs to properly verify all corner cases.
    PathFragment outputFile = PathFragment.create("very/output.txt");

    SandboxedSpawn spawn =
        new SandboxfsSandboxedSpawn(
            sandboxfs,
            outerDir,
            "workspace",
            ImmutableList.of("/bin/true"),
            ImmutableMap.of(),
            new SandboxInputs(ImmutableMap.of(), ImmutableSet.of(), ImmutableMap.of()),
            SandboxOutputs.create(ImmutableSet.of(outputFile), ImmutableSet.of()),
            ImmutableSet.of(),
            /* mapSymlinkTargets= */ false,
            new SynchronousTreeDeleter(),
            /* statisticsPath= */ null);
    spawn.createFileSystem();
    Path execRoot = spawn.getSandboxExecRoot();

    FileSystemUtils.createEmptyFile(execRoot.getRelative(outputFile));

    Path outputsDir = testRoot.getRelative("outputs");
    outputsDir.getRelative(outputFile.getParentDirectory()).createDirectoryAndParents();
    spawn.copyOutputs(outputsDir);

    assertThat(outputsDir.getRelative(outputFile).isFile(Symlinks.NOFOLLOW)).isTrue();
  }

  public void testSymlinks(boolean mapSymlinkTargets) throws Exception {
    Path input1 = workspaceDir.getRelative("dir1/input-1.txt");
    input1.getParentDirectory().createDirectory();
    FileSystemUtils.createEmptyFile(input1);

    Path input2 = workspaceDir.getRelative("dir1/input-2.txt");
    input2.getParentDirectory().createDirectory();
    FileSystemUtils.createEmptyFile(input2);

    Path linkToInput1 = workspaceDir.getRelative("dir2/link-to-input-1");
    linkToInput1.getParentDirectory().createDirectory();
    linkToInput1.createSymbolicLink(PathFragment.create("../dir1/input-1.txt"));
    assertThat(linkToInput1.readSymbolicLink().isAbsolute()).isFalse();

    Path linkToInput2 = workspaceDir.getRelative("dir2/link-to-input-2");
    linkToInput2.getParentDirectory().createDirectory();
    linkToInput2.createSymbolicLink(PathFragment.create("../dir1/input-2.txt"));
    assertThat(linkToInput2.readSymbolicLink().isAbsolute()).isFalse();

    Path linkToLink = workspaceDir.getRelative("dir2/link-to-link");
    linkToLink.getParentDirectory().createDirectory();
    linkToLink.createSymbolicLink(PathFragment.create("link-to-input-2"));
    assertThat(linkToLink.readSymbolicLink().isAbsolute()).isFalse();

    Path linkToAbsolutePath = workspaceDir.getRelative("dir2/link-to-absolute-path");
    linkToAbsolutePath.getParentDirectory().createDirectory();
    Path randomPath = workspaceDir.getRelative("/some-random-path");
    FileSystemUtils.createEmptyFile(randomPath);
    linkToAbsolutePath.createSymbolicLink(randomPath.asFragment());
    assertThat(linkToAbsolutePath.readSymbolicLink().isAbsolute()).isTrue();

    SandboxedSpawn spawn =
        new SandboxfsSandboxedSpawn(
            sandboxfs,
            outerDir,
            "workspace",
            ImmutableList.of("/bin/true"),
            ImmutableMap.of(),
            new SandboxInputs(
                ImmutableMap.of(
                    PathFragment.create("dir1/input-1.txt"), input1,
                    // input2 and linkToInput2 intentionally left unmapped to verify they are mapped
                    // as symlink targets of linktoLink.
                    PathFragment.create("such/link-1.txt"), linkToInput1,
                    PathFragment.create("such/link-to-link.txt"), linkToLink,
                    PathFragment.create("such/abs-link.txt"), linkToAbsolutePath),
                ImmutableSet.of(),
                ImmutableMap.of()),
            SandboxOutputs.create(
                ImmutableSet.of(PathFragment.create("very/output.txt")), ImmutableSet.of()),
            ImmutableSet.of(),
            mapSymlinkTargets,
            new SynchronousTreeDeleter(),
            /* statisticsPath= */ null);

    spawn.createFileSystem();
    Path execRoot = spawn.getSandboxExecRoot();

    // Relative symlinks must be kept as such in the sandbox and they must resolve properly.
    assertThat(execRoot.getRelative("such/link-1.txt").readSymbolicLink())
        .isEqualTo(PathFragment.create("../dir1/input-1.txt"));
    assertThat(execRoot.getRelative("such/link-1.txt").resolveSymbolicLinks()).isEqualTo(input1);
    assertThat(execRoot.getRelative("such/link-to-link.txt").readSymbolicLink())
        .isEqualTo(PathFragment.create("link-to-input-2"));
    if (mapSymlinkTargets) {
      assertThat(execRoot.getRelative("such/link-to-link.txt").resolveSymbolicLinks())
          .isEqualTo(input2);
      assertThat(execRoot.getRelative("such/link-to-input-2").readSymbolicLink())
          .isEqualTo(PathFragment.create("../dir1/input-2.txt"));
      assertThat(execRoot.getRelative("such/link-to-input-2").resolveSymbolicLinks())
          .isEqualTo(input2);
    } else {
      assertThrows(
          "Symlink resolution worked, which means the target was mapped when not expected",
          IOException.class,
          () -> execRoot.getRelative("such/link-to-link.txt").resolveSymbolicLinks());
    }

    // Targets of symlinks must have been mapped inside the sandbox only when requested.
    assertThat(execRoot.getRelative("dir1/input-1.txt").exists()).isTrue();
    if (mapSymlinkTargets) {
      assertThat(execRoot.getRelative("dir1/input-2.txt").exists()).isTrue();
    } else {
      assertThat(execRoot.getRelative("dir1/input-2.txt").exists()).isFalse();
    }

    // Absolute symlinks must be kept as such in the sandbox no matter where they point to.
    assertThat(execRoot.getRelative("such/abs-link.txt").isSymbolicLink()).isTrue();
    assertThat(execRoot.getRelative("such/abs-link.txt").readSymbolicLinkUnchecked())
        .isEqualTo(randomPath.asFragment());
  }

  @Test
  public void testSymlinks_TargetsMappedIfRequested() throws Exception {
    testSymlinks(true);
  }

  @Test
  public void testSymlinks_TargetsNotMappedIfNotRequested() throws Exception {
    testSymlinks(false);
  }
}
