// 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.hash.HashCode;
import com.google.devtools.build.lib.actions.Root;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.skyframe.serialization.PathCodec;
import com.google.devtools.build.lib.skyframe.serialization.SerializationException;
import com.google.devtools.build.lib.skyframe.serialization.strings.StringCodecs;
import com.google.devtools.build.lib.util.StringCanonicalizer;
import com.google.devtools.build.lib.vfs.Path;
import com.google.protobuf.CodedInputStream;
import com.google.protobuf.CodedOutputStream;
import java.io.IOException;
import java.util.Objects;

/**
 * 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!
 */
@Immutable
public final class BlazeDirectories {

  // Include directory name, relative to execRoot/blaze-out/configuration.
  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 all build actions. */
  private final Path execRoot;

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

  public BlazeDirectories(
      ServerDirectories serverDirectories,
      Path workspace,
      String productName) {
    this.serverDirectories = serverDirectories;
    this.workspace = workspace;
    this.productName = productName;
    Path outputBase = serverDirectories.getOutputBase();
    Path execRootBase = outputBase.getChild("execroot");
    boolean useDefaultExecRootName = this.workspace == null || this.workspace.isRootDirectory();
    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.execRoot = execRootBase.getChild(DEFAULT_EXEC_ROOT);
    } else {
      this.execRoot = execRootBase.getChild(workspace.getBaseName());
    }
    String relativeOutputPath = getRelativeOutputPath(productName);
    this.outputPath = execRoot.getRelative(getRelativeOutputPath());
    this.localOutputPath = outputBase.getRelative(relativeOutputPath);
  }

  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 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();
  }

  /**
   * Returns the execution root for the main package. This is created before the workspace file
   * has been read, so it has an incorrect path.  Use {@link #getExecRoot(String)} instead.
   */
  @Deprecated
  public Path getExecRoot() {
    return execRoot;
  }

  /**
   * 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 execRoot.getParentDirectory().getRelative(workspaceName);
  }

  /**
   * Returns the output path for the main repository using the workspace's directory name. Use
   * {@link #getOutputPath(String)}, instead.
   */
  @Deprecated
  public Path getOutputPath() {
    return outputPath;
  }

  /**
   * 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 the stdout/stderr for actions can be stored temporarily for a
   * build. If the directory already exists, the directory is cleaned.
   */
  public Path getActionConsoleOutputDirectory(Path execRoot) {
    return execRoot.getRelative(getRelativeOutputPath()).getRelative("_tmp/action_outs");
  }

  /**
   * 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 Root getBuildDataDirectory(String workspaceName) {
    return Root
        .asDerivedRoot(getExecRoot(workspaceName), getOutputPath(workspaceName), true);
  }

 /**
  * 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() {
    // execRoot is derivable from other fields, but better safe than sorry.
    return Objects.hash(serverDirectories, workspace, productName, execRoot);
  }

  @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)
        // execRoot is derivable from other fields, but better safe than sorry.
        && this.execRoot.equals(that.execRoot);
  }

  void serialize(CodedOutputStream codedOut, PathCodec pathCodec)
      throws IOException, SerializationException {
    serverDirectories.serialize(codedOut, pathCodec);
    pathCodec.serialize(workspace, codedOut);
    StringCodecs.asciiOptimized().serialize(productName, codedOut);
  }

  static BlazeDirectories deserialize(CodedInputStream codedIn, PathCodec pathCodec)
      throws IOException, SerializationException {
    return new BlazeDirectories(
        ServerDirectories.deserialize(codedIn, pathCodec),
        pathCodec.deserialize(codedIn),
        StringCodecs.asciiOptimized().deserialize(codedIn));
  }
}
