// 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.base.Preconditions.checkArgument;

import com.google.devtools.build.lib.sandbox.SandboxfsProcess.Mapping;
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.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;

/**
 * Creates an execRoot for a Spawn that contains all required input files by mounting a sandboxfs
 * FUSE filesystem on the provided path.
 */
class SandboxfsSandboxedSpawn implements SandboxedSpawn {
  private static final Logger log = Logger.getLogger(SandboxfsSandboxedSpawn.class.getName());

  /** Sequence number to assign a unique subtree to each action within the mount point. */
  private static final AtomicInteger lastId = new AtomicInteger();

  /** The sandboxfs instance to use for this spawn. */
  private final SandboxfsProcess process;

  /** Arguments to pass to the spawn, including the binary name. */
  private final List<String> arguments;

  /** Environment variables to pass to the spawn. */
  private final Map<String, String> environment;

  /** Collection of input files to be made available to the spawn in read-only mode. */
  private final Map<PathFragment, Path> inputs;

  /** Collection of output files to expect from the spawn. */
  private final Collection<PathFragment> outputs;

  /** Collection of directories where the spawn can write files to relative to {@link #execRoot}. */
  private final Set<PathFragment> writableDirs;

  /**
   * Writable directory to support the writes performed by the command. This acts as the target
   * of all writable mappings in the sandboxfs instance.
   */
  private final Path sandboxScratchDir;

  /** Path to the working directory of the command. */
  private final Path execRoot;

  /**
   * Path to the working directory of the command, seen as an absolute path that starts at
   * the sandboxfs's mount point.
   */
  private final PathFragment innerExecRoot;

  /**
   * Constructs a new sandboxfs-based spawn runner.
   *
   * @param process sandboxfs instance to use for this spawn
   * @param outerDir writable directory where the spawn runner keeps control files
   * @param arguments arguments to pass to the spawn, including the binary name
   * @param environment environment variables to pass to the spawn
   * @param inputs input files to be made available to the spawn in read-only mode
   * @param outputs output files to expect from the spawn
   * @param writableDirs directories where the spawn can write files to, relative to the sandbox's
   *     dynamically-allocated execroot
   */
  SandboxfsSandboxedSpawn(
      SandboxfsProcess process,
      Path outerDir,
      List<String> arguments,
      Map<String, String> environment,
      Map<PathFragment, Path> inputs,
      Collection<PathFragment> outputs,
      Set<PathFragment> writableDirs) {
    this.process = process;
    this.arguments = arguments;
    this.environment = environment;
    this.inputs = inputs;
    for (PathFragment path : outputs) {
      checkArgument(!path.isAbsolute(), "outputs %s must be relative", path);
    }
    this.outputs = outputs;
    for (PathFragment path : writableDirs) {
      checkArgument(!path.isAbsolute(), "writable directory %s must be relative", path);
    }
    this.writableDirs = writableDirs;

    this.sandboxScratchDir = outerDir.getRelative("scratch");

    int id = lastId.getAndIncrement();
    this.execRoot = process.getMountPoint().getRelative("" + id);
    this.innerExecRoot = PathFragment.create("/" + id);
  }

  @Override
  public Path getSandboxExecRoot() {
    return execRoot;
  }

  @Override
  public List<String> getArguments() {
    return arguments;
  }

  @Override
  public Map<String, String> getEnvironment() {
    return environment;
  }

  @Override
  public void createFileSystem() throws IOException {
    sandboxScratchDir.createDirectory();

    reconfigure(inputs, writableDirs, outputs);
  }

  @Override
  public void copyOutputs(Path targetExecRoot) throws IOException {
    // TODO(jmmv): If we knew the targetExecRoot when setting up the spawn, we may be able to
    // configure sandboxfs so that the output files are written directly to their target locations.
    // This would avoid having to move them after-the-fact.
    SandboxedSpawn.moveOutputs(outputs, sandboxScratchDir, targetExecRoot);
  }

  @Override
  public void delete() {
    try {
      process.unmap(innerExecRoot);
    } catch (IOException e) {
      // We use independent subdirectories for each action, so a failure to unmap one, while
      // annoying, is not a big deal.  The sandboxfs instance will be unmounted anyway after
      // the build, which will cause these to go away anyway.
      log.warning("Cannot unmap " + innerExecRoot + ": " + e);
    }
  }

  /**
   * Creates a new set of mappings to sandbox the given inputs.
   *
   * @param inputs collection of paths to expose within the sandbox as read-only mappings, given
   *     as a map of mapped path to target path. The target path may be null, in which case an empty
   *     read-only file is mapped.
   * @return the collection of mappings to use for reconfiguration
   * @throws IOException if we fail to resolve symbolic links
   */
  private List<Mapping> createMappings(Map<PathFragment, Path> inputs) throws IOException {
    List<Mapping> mappings = new ArrayList<>();

    mappings.add(Mapping.builder()
        .setPath(innerExecRoot)
        .setTarget(sandboxScratchDir.asFragment())
        .setWritable(true)
        .build());

    // Path to the empty file used as the target of mappings that don't provide one.  This is
    // lazily created and initialized only when we need such a mapping.  It's safe to share the
    // same empty file across all such mappings because this file is exposed as read-only.
    //
    // We cannot use /dev/null, as we used to do in the past, because exposing devices via a
    // FUSE file system (which sandboxfs is) requires root privileges.
    Path emptyFile = null;

    for (Map.Entry<PathFragment, Path> entry : inputs.entrySet()) {
      PathFragment target;
      if (entry.getValue() == null) {
        if (emptyFile == null) {
          emptyFile = sandboxScratchDir.getRelative("empty");
          FileSystemUtils.createEmptyFile(emptyFile);
        }
        target = emptyFile.asFragment();
      } else if (entry.getValue().isSymbolicLink()) {
        // If an input is a symlink, we don't necessarily have its target as an input as well.  To
        // ensure the target is reachable within the sandbox, we have two choices: we can either
        // expose the target in the sandbox and respect the symlink, or we can resolve what the
        // actual target is and point the mapping there.  The former has higher fidelity, as the
        // sandbox will respect the file's type as a symlink.  The latter is easier to implement
        // and is slightly faster, as we avoid having to resolve symlinks later via sandboxfs.
        // Therefore, do the latter until proven insufficient.
        target = entry.getValue().resolveSymbolicLinks().asFragment();
      } else {
        target = entry.getValue().asFragment();
      }
      mappings.add(Mapping.builder()
          .setPath(innerExecRoot.getRelative(entry.getKey()))
          .setTarget(target)
          .setWritable(false)
          .build());
    }

    return mappings;
  }

  /**
   * Pushes a new configuration to sandboxfs and waits for acceptance.
   *
   * @param inputs collection of paths to expose within the sandbox as read-only mappings, given
   *     as a map of mapped path to target path. The target path may be null, in which case an empty
   *     file is mapped.
   * @param writableDirs collection of writable paths to create within the read-write portion of
   *     the sandbox
   * @param outputs collection of outputs to expect within the read-write portion of the sandbox
   * @throws IOException if reconfiguration fails
   */
  private void reconfigure(Map<PathFragment, Path> inputs, Set<PathFragment> writableDirs,
      Collection<PathFragment> outputs) throws IOException {
    List<Mapping> mappings = createMappings(inputs);

    Set<PathFragment> dirsToCreate = new HashSet<>(writableDirs);
    for (PathFragment output : outputs) {
      dirsToCreate.add(output.getParentDirectory());
    }
    for (PathFragment input : inputs.keySet()) {
      // We must pre-create the directory layout for input files as well as for output files.
      // The reason is that we map the root directory as writable within the sandbox and later
      // map read-only files on top of it. We want the intermediate components on those paths
      // to remain writable within the top-level root directory we have mounted, but that's
      // only possible if we pre-create those. Otherwise, sandboxfs will see that those components
      // do not exist when mapping the read-only file and will generate fake, in-memory, read-only
      // components for them.
      dirsToCreate.add(input.getParentDirectory());
    }
    for (PathFragment dir : dirsToCreate) {
      sandboxScratchDir.getRelative(dir).createDirectoryAndParents();
    }

    process.map(mappings);
  }
}
