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

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Ascii;
import com.google.common.hash.HashCode;
import com.google.devtools.build.lib.actions.ArtifactRoot;
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.util.StringCanonicalizer;
import com.google.devtools.build.lib.vfs.Path;
import java.util.Objects;
import javax.annotation.Nullable;

/**
 * Encapsulates the directories related to a workspace.
 *
 * <p>The <code>workspace</code> is the top-level directory in the user's client (possibly
 * read-only). The <code>execRoot</code> is the working directory for all spawned tools, which is
 * generally below the <code>outputBase</code>.
 *
 * <p>Care must be taken to avoid multiple Bazel instances trying to write to the same output
 * directory. At this time, this is enforced by requiring a 1:1 correspondence between a running
 * Bazel instance and an output base directory, though this requirement may be softened in the
 * future.
 *
 * <p>If the user does not qualify an output base directory, the startup code will derive it
 * deterministically from the workspace. Note also that while the Bazel server process runs with the
 * workspace directory as its working directory, the client process may have a different working
 * directory, typically a subdirectory.
 *
 * <p>Do not put shortcuts to specific files here!
 */
@AutoCodec
@Immutable
public final class BlazeDirectories {
  // Include directory name, relative to execRoot/blaze-out/configuration. Only one segment allowed.
  public static final String RELATIVE_INCLUDE_DIR = StringCanonicalizer.intern("include");
  @VisibleForTesting static final String DEFAULT_EXEC_ROOT = "default-exec-root";

  private final ServerDirectories serverDirectories;
  /** Workspace root and server CWD. */
  private final Path workspace;
  /**
   * The root of the user's local JDK install, to be used as the default target javabase and as a
   * fall-back host_javabase. This is not the embedded JDK.
   */
  private final Path defaultSystemJavabase;
  /** The root of all build actions. */
  private final Path blazeExecRoot;

  // These two are kept to avoid creating new objects every time they are accessed. This showed up
  // in a profiler.
  private final Path blazeOutputPath;
  private final Path localOutputPath;
  private final String productName;

  @AutoCodec.Instantiator
  public BlazeDirectories(
      ServerDirectories serverDirectories,
      Path workspace,
      Path defaultSystemJavabase,
      String productName) {
    this.serverDirectories = serverDirectories;
    this.workspace = workspace;
    this.defaultSystemJavabase = defaultSystemJavabase;
    this.productName = productName;
    Path outputBase = serverDirectories.getOutputBase();
    if (Ascii.equalsIgnoreCase(productName, "blaze")) {
      boolean useDefaultExecRootName =
          this.workspace == null || this.workspace.getParentDirectory() == null;
      if (useDefaultExecRootName) {
        // TODO(bazel-team): if workspace is null execRoot should be null, but at the moment there
        // is a lot of code that depends on it being non-null.
        this.blazeExecRoot = serverDirectories.getExecRootBase().getChild(DEFAULT_EXEC_ROOT);
      } else {
        this.blazeExecRoot = serverDirectories.getExecRootBase().getChild(workspace.getBaseName());
      }
      this.blazeOutputPath = blazeExecRoot.getRelative(getRelativeOutputPath());
    } else {
      this.blazeExecRoot = null;
      this.blazeOutputPath = null;
    }
    this.localOutputPath = outputBase.getRelative(getRelativeOutputPath());
  }

  public ServerDirectories getServerDirectories() {
    return serverDirectories;
  }

  /**
   * Returns the base of the output tree, which hosts all build and scratch output for a user and
   * workspace.
   */
  public Path getInstallBase() {
    return serverDirectories.getInstallBase();
  }

  /** Returns the workspace directory, which is also the working dir of the server. */
  public Path getWorkspace() {
    return workspace;
  }

  /** Returns the root of the user's local JDK install (not the embedded JDK). */
  public Path getLocalJavabase() {
    return defaultSystemJavabase;
  }

  /** Returns if the workspace directory is a valid workspace. */
  public boolean inWorkspace() {
    return this.workspace != null;
  }

  /**
   * Returns the base of the output tree, which hosts all build and scratch output for a user and
   * workspace.
   */
  public Path getOutputBase() {
    return serverDirectories.getOutputBase();
  }

  public Path getExecRootBase() {
    return serverDirectories.getExecRootBase();
  }

  /**
   * Returns the execution root of Blaze.
   *
   * @deprecated Avoid using this method as it will only work if your workspace is named like
   *     Google's internal workspace. This method will not work in Bazel. Use {@link
   *     #getExecRoot(String)} instead.
   *     <p><em>AVOID USING THIS METHOD</em>
   */
  @Nullable
  @Deprecated
  public Path getBlazeExecRoot() {
    return blazeExecRoot;
  }

  /**
   * Returns the execution root for a particular repository. This is the directory underneath which
   * Blaze builds the source symlink forest, to represent the merged view of different workspaces
   * specified with --package_path.
   */
  public Path getExecRoot(String workspaceName) {
    return serverDirectories.getExecRootBase().getRelative(workspaceName);
  }

  /**
   * Returns the output path of Blaze.
   *
   * @deprecated Avoid using this method as it will only work if your workspace is named like
   *     Google's internal workspace. This method will not work in Bazel. Use {@link
   *     #getOutputPath(String)} instead.
   *     <p><em>AVOID USING THIS METHOD</em>
   */
  @Nullable
  @Deprecated
  public Path getBlazeOutputPath() {
    return blazeOutputPath;
  }

  /** Returns the output path used by this Blaze instance. */
  public Path getOutputPath(String workspaceName) {
    return getExecRoot(workspaceName).getRelative(getRelativeOutputPath());
  }

  /** Returns the local output path used by this Blaze instance. */
  public Path getLocalOutputPath() {
    return localOutputPath;
  }

  /**
   * Returns the directory where actions can store temporary files (such as their stdout and stderr)
   * during a build. If the directory already exists, the directory is cleaned.
   */
  public Path getActionTempsDirectory(Path execRoot) {
    return execRoot.getRelative(getRelativeOutputPath()).getRelative("_tmp/actions");
  }

  public Path getPersistentActionOutsDirectory(Path execRoot) {
    return execRoot.getRelative(getRelativeOutputPath()).getRelative("_actions");
  }

  /** Returns the installed embedded binaries directory, under the shared installBase location. */
  public Path getEmbeddedBinariesRoot() {
    return serverDirectories.getEmbeddedBinariesRoot();
  }

  /**
   * Returns the configuration-independent root where the build-data should be placed, given the
   * {@link BlazeDirectories} of this server instance. Nothing else should be placed here.
   */
  public ArtifactRoot getBuildDataDirectory(String workspaceName) {
    return ArtifactRoot.asDerivedRoot(
        getExecRoot(workspaceName), getRelativeOutputPath(productName));
  }

  /**
   * Returns the MD5 content hash of the blaze binary (includes deploy JAR, embedded binaries, and
   * anything else that ends up in the install_base).
   */
  public HashCode getInstallMD5() {
    return serverDirectories.getInstallMD5();
  }

  public String getRelativeOutputPath() {
    return BlazeDirectories.getRelativeOutputPath(productName);
  }

  public String getProductName() {
    return productName;
  }

  /**
   * Returns the output directory name, relative to the execRoot. TODO(bazel-team): (2011) make this
   * private?
   */
  public static String getRelativeOutputPath(String productName) {
    return StringCanonicalizer.intern(productName + "-out");
  }

  @Override
  public int hashCode() {
    // blazeExecRoot is derivable from other fields, but better safe than sorry.
    return Objects.hash(serverDirectories, workspace, productName);
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (!(obj instanceof BlazeDirectories)) {
      return false;
    }
    BlazeDirectories that = (BlazeDirectories) obj;
    return this.serverDirectories.equals(that.serverDirectories)
        && this.workspace.equals(that.workspace)
        && this.productName.equals(that.productName);
  }
}
