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

import com.google.common.collect.ImmutableMap;
import com.google.common.io.Files;
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 java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Creates an execRoot for a Spawn that contains input files as symlinks to hardlinks of the
 * original input files.
 */
public class HardlinkedExecRoot implements SandboxExecRoot {

  private final Path execRoot;
  private final Path sandboxPath;
  private final Path sandboxExecRoot;
  private final PrintWriter errWriter;

  public HardlinkedExecRoot(
      Path execRoot, Path sandboxPath, Path sandboxExecRoot, PrintWriter errWriter) {
    this.execRoot = execRoot;
    this.sandboxPath = sandboxPath;
    this.sandboxExecRoot = sandboxExecRoot;
    this.errWriter = errWriter;
  }

  @Override
  public void createFileSystem(
      Map<PathFragment, Path> inputs, Collection<PathFragment> outputs, Set<Path> writableDirs)
      throws IOException {
    Set<Path> createdDirs = new HashSet<>();
    FileSystemUtils.createDirectoryAndParentsWithCache(createdDirs, sandboxExecRoot);
    createDirectoriesForOutputs(outputs, createdDirs);

    // Create all needed directories.
    for (Path createDir : writableDirs) {
      if (errWriter != null) {
        errWriter.printf("createdir: %s\n", createDir.getPathString());
      }
      FileSystemUtils.createDirectoryAndParents(createDir);
    }

    // Link all the inputs.
    linkInputs(inputs);
  }

  private void createDirectoriesForOutputs(Collection<PathFragment> outputs, Set<Path> createdDirs)
      throws IOException {
    // Prepare the output directories in the sandbox.
    for (PathFragment output : outputs) {
      FileSystemUtils.createDirectoryAndParentsWithCache(
          createdDirs, sandboxExecRoot.getRelative(output.getParentDirectory()));
    }
  }

  /**
   * Make all specified inputs available in the sandbox.
   *
   * <p>We want the sandboxed process to have access only to these input files and not anything else
   * from the workspace. Furthermore, the process should not be able to modify these input files. We
   * achieve this by hardlinking all input files into a temporary "inputs" directory, then
   * symlinking them into their correct place inside the sandbox.
   *
   * <p>The hardlinks / symlinks combination (as opposed to simply directly hardlinking to the final
   * destination) is necessary, because we build a solib symlink tree for shared libraries where the
   * original file and the created symlink have two different file names (libblaze_util.so vs.
   * src_Stest_Scpp_Sblaze_Uutil_Utest.so) and our cc_wrapper.sh needs to be able to figure out both
   * names (by following solib symlinks back) to modify the paths to the shared libraries in
   * cc_binaries.
   */
  private void linkInputs(Map<PathFragment, Path> inputs) throws IOException {
    // Create directory for input files.
    Path inputsDir = sandboxPath.getRelative("inputs");
    if (!inputsDir.exists()) {
      inputsDir.createDirectory();
    }

    for (ImmutableMap.Entry<PathFragment, Path> entry : inputs.entrySet()) {
      // Hardlink, resolve symlink here instead in finalizeLinks.
      Path target = entry.getValue().resolveSymbolicLinks();
      Path hardlinkName =
          target.startsWith(execRoot)
              ? inputsDir.getRelative(target.relativeTo(execRoot))
              : inputsDir.getRelative(entry.getKey());
      if (errWriter != null) {
        errWriter.printf("hardlink: %s -> %s\n", hardlinkName, target);
      }
      try {
        createHardLink(hardlinkName, target);
      } catch (IOException e) {
        // Creating a hardlink might fail when the input file and the sandbox directory are not on
        // the same filesystem / device. Then we use symlink instead.
        hardlinkName.createSymbolicLink(target);
      }

      // symlink
      Path symlinkName = sandboxExecRoot.getRelative(entry.getKey());
      if (errWriter != null) {
        errWriter.printf("symlink: %s -> %s\n", symlinkName, hardlinkName);
      }
      FileSystemUtils.createDirectoryAndParents(symlinkName.getParentDirectory());
      symlinkName.createSymbolicLink(hardlinkName);
    }
  }

  private void createHardLink(Path target, Path source) throws IOException {
    java.nio.file.Path targetNio = java.nio.file.Paths.get(target.toString());
    java.nio.file.Path sourceNio = java.nio.file.Paths.get(source.toString());

    if (!source.exists() || target.exists()) {
      return;
    }
    // Regular file
    if (source.isFile()) {
      Path parentDir = target.getParentDirectory();
      if (!parentDir.exists()) {
        FileSystemUtils.createDirectoryAndParents(parentDir);
      }
      java.nio.file.Files.createLink(targetNio, sourceNio);
      // Directory
    } else if (source.isDirectory()) {
      Collection<Path> subpaths = source.getDirectoryEntries();
      for (Path sourceSubpath : subpaths) {
        Path targetSubpath = target.getRelative(sourceSubpath.relativeTo(source));
        createHardLink(targetSubpath, sourceSubpath);
      }
    }
  }

  @Override
  public void copyOutputs(Path execRoot, Collection<PathFragment> outputs) throws IOException {
    for (PathFragment output : outputs) {
      Path source = sandboxExecRoot.getRelative(output);
      Path target = execRoot.getRelative(output);
      if (source.isFile() || source.isSymbolicLink()) {
        Files.move(source.getPathFile(), target.getPathFile());
      } else if (source.isDirectory()) {
        try {
          source.renameTo(target);
        } catch (IOException e) {
          // Failed to move directory directly, thus move it recursively.
          target.createDirectory();
          FileSystemUtils.moveTreesBelow(source, target);
        }
      }
    }
  }
}
