// Copyright 2014 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.actions;

import com.google.common.base.Preconditions;
import com.google.common.collect.Interner;
import com.google.common.collect.Interners;
import com.google.devtools.build.lib.actions.Artifact.DerivedArtifact;
import com.google.devtools.build.lib.actions.Artifact.SourceArtifact;
import com.google.devtools.build.lib.cmdline.LabelConstants;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.starlarkbuildapi.FileRootApi;
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 java.util.Objects;
import net.starlark.java.eval.Printer;

/**
 * A root for an artifact. The roots are the directories containing artifacts, and they are mapped
 * together into a single directory tree to form the execution environment. There are two kinds of
 * roots: source roots and derived roots. Source roots correspond to entries of the package path,
 * and they can be anywhere on disk. Derived roots correspond to output directories; there are
 * generally different output directories for different configurations, and different types of
 * output (bin, genfiles, includes, etc.).
 *
 * <p>When mapping the roots into a single directory tree, the source roots are merged, such that
 * each package is accessed in its entirety from a single source root. The package cache is
 * responsible for determining that mapping. The derived roots, on the other hand, have to be
 * distinct. (It is currently allowed to have a derived root that is the prefix of another one.)
 *
 * <p>Derived roots must have paths that point inside the exec root ({@link
 * com.google.devtools.build.lib.analysis.BlazeDirectories#getExecRoot}), i.e. below the directory
 * that is the root of the merged directory tree.
 *
 * <p>For example, if
 *
 * <ul>
 *   <li>your workspace is {@code /home/my_workspace/}
 *   <li>your package path is {@code /home/my_workspace/} (the norm unless you're customizing {@link
 *       com.google.devtools.build.lib.pkgcache.PackageOptions#packagePath}).
 *   <li>your workspace has a source file at {@code /home/my_workspace/myapp/source.go}
 *   <li>you build a binary that outputs {@code /home/my_workspace/bazel-out/x86-opt/bin/a/mybinary}
 * </ul>
 *
 * <p>then
 *
 * <ul>
 *   <li>Bazel creates an "output base" directory {@code $OUTPUT_BASE} which it uses for staging
 *       build work: {@link com.google.devtools.build.lib.analysis.BlazeDirectories#getOutputBase()}
 *   <li>Bazel creates an exec root at {@code $OUTPUT_BASE/execroot/my_workspace/}. This symlinks
 *       all files and directories under {@code /home/my_workspace/}. This is the working directory
 *       where actions run (either directly for local execution or as the base for staging remote
 *       execution paths). This is also the base directory for writing outputs.
 *   <li>{@code /home/my_workspace/myapp/source.go} is a {@link SourceArtifact} with source root
 *       {@code /home/my_workspace/}
 *   <li>{@code /home/my_workspace/bazel-out/x86-opt/bin/a/mybinary} is a {@link DerivedArtifact}.
 *       Because derived artifacts are written under the exec root, {@code
 *       /home/my_workspace/bazel-out} is a symlink to {@code $EXEC_ROOT/bazel-out}. So {@code
 *       mybinary} is actually at {@code $EXEC_ROOT/bazel-out/x86-opt/bin/mybinary}. Its derived
 *       root is therefore {@code $EXEC_ROOT/bazel-out/x86-opt/bin/}.
 * </ul>
 *
 * <p>The "exec path" ({@link Artifact#getExecPath()}, {@link #getExecPath()}, etc.) is an entity's
 * path relative to the exec root. So {@code /home/my_workspace/myapp/source.go}'s exec path is
 * {@code myapp/source.go} and {@code /home/my_workspace/bazel-out/x86-opt/bin/a/mybinary}'s exec
 * path is {@code bazel-out/x86-opt/bin/a/mybinary}
 *
 * <p>The "root-relative path" ({@link Artifact#getRootRelativePath()}) is a entity's path relative
 * to its root. So {@code /home/my_workspace/myapp/source.go}'s root-relative path is {@code
 * myapp/source.go} and {@code /home/my_workspace/bazel-out/x86-opt/bin/a/mybinary}'s root-relative
 * path is {@code a/mybinary}.
 *
 * <p>For concrete examples, run {@code $ bazel info} in your terminal after a build. Also see <a
 * href="https://bazel.build/remote/output-directories">Bazel's output directory docs</a>.
 */
@AutoCodec
@Immutable
public final class ArtifactRoot implements Comparable<ArtifactRoot>, FileRootApi {
  private static final Interner<ArtifactRoot> INTERNER = Interners.newWeakInterner();
  /**
   * Do not use except in tests and in {@link
   * com.google.devtools.build.lib.skyframe.SkyframeExecutor}.
   *
   * <p>Returns the given path as a source root. The path may not be {@code null}.
   */
  public static ArtifactRoot asSourceRoot(Root root) {
    return INTERNER.intern(
        new ArtifactRoot(root, PathFragment.EMPTY_FRAGMENT, RootType.MainSource));
  }

  /**
   * Do not use except in tests and in {@link
   * com.google.devtools.build.lib.skyframe.SkyframeExecutor}.
   *
   * <p>Returns the given path as the external source root. The path should end with {@link
   * LabelConstants.EXTERNAL_REPOSITORY_LOCATION} since the external repository root is always
   * $OUTPUT_BASE/external regardless of the layout of the exec root.
   */
  public static ArtifactRoot asExternalSourceRoot(Root root) {
    Preconditions.checkArgument(
        root.asPath()
            .asFragment()
            .getParentDirectory()
            .endsWith(LabelConstants.EXTERNAL_REPOSITORY_LOCATION));
    return INTERNER.intern(
        new ArtifactRoot(root, PathFragment.EMPTY_FRAGMENT, RootType.ExternalSource));
  }

  /**
   * Constructs an ArtifactRoot given the output prefixes. (eg, "bin"), and (eg, "testlogs")
   * relative to the execRoot.
   *
   * <p>Be careful with this method - all derived roots must be within the derived artifacts tree,
   * defined in ArtifactFactory (see {@link ArtifactFactory#isDerivedArtifact(PathFragment)}).
   *
   * <p>Call {@link #asDerivedRoot(Path, RootType, PathFragment)} if you already have a {@link
   * PathFragment} instance for the exec path.
   */
  public static ArtifactRoot asDerivedRoot(Path execRoot, RootType rootType, String... prefixes) {
    PathFragment execPath = PathFragment.EMPTY_FRAGMENT;
    for (String prefix : prefixes) {
      // Tests can have empty segments here, be gentle to them.
      if (!prefix.isEmpty()) {
        execPath = execPath.getChild(prefix);
      }
    }
    return asDerivedRoot(execRoot, rootType, execPath);
  }

  /**
   * Constructs an {@link ArtifactRoot} given the execPath, relative to the execRoot.
   *
   * <p>Be careful with this method - all derived roots must be within the derived artifacts tree,
   * defined in ArtifactFactory (see {@link ArtifactFactory#isDerivedArtifact(PathFragment)}).
   */
  public static ArtifactRoot asDerivedRoot(
      Path execRoot, RootType rootType, PathFragment execPath) {
    // Make sure that we are not creating a derived artifact under the execRoot.
    Preconditions.checkArgument(!execPath.isEmpty(), "empty execPath");
    Preconditions.checkArgument(!execPath.isAbsolute(), "execPath must be relative: %s", execPath);
    Preconditions.checkArgument(
        !execPath.containsUplevelReferences(),
        "execPath: %s contains parent directory reference (..)",
        execPath);
    Preconditions.checkArgument(
        isOutputRootType(rootType) || isMiddlemanRootType(rootType),
        "%s is not a derived root type",
        rootType);
    Path root = execRoot.getRelative(execPath);
    return INTERNER.intern(new ArtifactRoot(Root.fromPath(root), execPath, rootType));
  }

  @AutoCodec.VisibleForSerialization
  @AutoCodec.Instantiator
  static ArtifactRoot createForSerialization(
      Root rootForSerialization, PathFragment execPath, RootType rootType) {
    if (!isOutputRootType(rootType)) {
      return INTERNER.intern(new ArtifactRoot(rootForSerialization, execPath, rootType));
    }
    return asDerivedRoot(rootForSerialization.asPath(), rootType, execPath);
  }

  /**
   * ArtifactRoot types. Callers of asDerivedRoot methods need to specify which type of derived root
   * artifact they want to create, which is why this enum is public.
   */
  public enum RootType {
    MainSource,
    ExternalSource,
    Output,
    Middleman,
    // Sibling root types are in effect when --experimental_sibling_repository_layout is activated.
    // These will eventually replace the above Output and Middleman types when the flag becomes
    // the default option and then removed.
    SiblingMainOutput,
    SiblingMainMiddleman,
    SiblingExternalOutput,
    SiblingExternalMiddleman,
  }

  private final Root root;
  private final PathFragment execPath;
  private final RootType rootType;

  private ArtifactRoot(Root root, PathFragment execPath, RootType rootType) {
    this.root = Preconditions.checkNotNull(root);
    this.execPath = execPath;
    this.rootType = rootType;
  }

  @Override
  public boolean isImmutable() {
    return true; // immutable and Starlark-hashable
  }

  public Root getRoot() {
    return root;
  }

  /**
   * Returns the path fragment from the exec root to the actual root. For source roots, this returns
   * the empty fragment.
   */
  public PathFragment getExecPath() {
    return execPath;
  }

  @Override
  public String getExecPathString() {
    return execPath.getPathString();
  }

  public boolean isSourceRoot() {
    return rootType == RootType.MainSource || rootType == RootType.ExternalSource;
  }

  private static boolean isOutputRootType(RootType rootType) {
    return rootType == RootType.SiblingMainOutput
        || rootType == RootType.SiblingExternalOutput
        || rootType == RootType.Output;
  }

  private static boolean isMiddlemanRootType(RootType rootType) {
    return rootType == RootType.SiblingMainMiddleman
        || rootType == RootType.SiblingExternalMiddleman
        || rootType == RootType.Middleman;
  }

  boolean isMiddlemanRoot() {
    return isMiddlemanRootType(rootType);
  }

  public boolean isExternal() {
    return rootType == RootType.ExternalSource
        || rootType == RootType.SiblingExternalOutput
        || rootType == RootType.SiblingExternalMiddleman;
  }

  /**
   * Returns true if the ArtifactRoot is a legacy derived root type, i.e. a derived root type
   * created without the --experimental_sibling_repository_layout flag set.
   */
  public boolean isLegacy() {
    return rootType == RootType.Output || rootType == RootType.Middleman;
  }

  @Override
  public int compareTo(ArtifactRoot o) {
    return root.compareTo(o.root);
  }

  @Override
  public int hashCode() {
    return Objects.hash(root, execPath, rootType);
  }

  /**
   * The Root of a derived ArtifactRoot contains the exec path. In order to avoid duplicating that
   * path, and enable the Root to be serialized as a constant, we return the "exec root" Root here,
   * by stripping the exec path. That Root is likely to be serialized as a constant by {@link
   * Root.RootCodec}, saving a lot of serialized bytes on the wire.
   */
  @SuppressWarnings("unused") // Used by @AutoCodec.
  Root getRootForSerialization() {
    if (!isOutputRootType(rootType)) {
      return root;
    }
    // Find fragment of root that does not include execPath and return just that root. It is likely
    // to be serialized as a constant by RootCodec. For instance, if the original exec root was
    // /execroot, and this root was /execroot/bazel-out/bin, with execPath bazel-out/bin, then we
    // just serialize /execroot and bazel-out/bin separately.
    // We just want to strip execPath from root, but I don't know a trivial way to do that.
    PathFragment rootFragment = root.asPath().asFragment();
    return Root.fromPath(
        root.asPath()
            .getFileSystem()
            .getPath(
                rootFragment.subFragment(
                    0, rootFragment.segmentCount() - execPath.segmentCount())));
  }

  @Override
  public boolean equals(Object o) {
    if (o == this) {
      return true;
    }
    if (!(o instanceof ArtifactRoot)) {
      return false;
    }
    ArtifactRoot r = (ArtifactRoot) o;
    return root.equals(r.root) && execPath.equals(r.execPath) && rootType == r.rootType;
  }

  @Override
  public String toString() {
    return root + (isSourceRoot() ? "[source]" : "[derived]");
  }

  @Override
  public void repr(Printer printer) {
    printer.append(isSourceRoot() ? "<source root>" : "<derived root>");
  }
}
