// 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.rules.cpp;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.actions.AbstractAction;
import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
import com.google.devtools.build.lib.actions.ActionExecutionContext;
import com.google.devtools.build.lib.actions.ActionExecutionException;
import com.google.devtools.build.lib.actions.ActionKeyContext;
import com.google.devtools.build.lib.actions.ActionOwner;
import com.google.devtools.build.lib.actions.ActionRegistry;
import com.google.devtools.build.lib.actions.ActionResult;
import com.google.devtools.build.lib.actions.Actions;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.ArtifactRoot;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.actions.ActionConstructionContext;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.server.FailureDetails.FailureDetail;
import com.google.devtools.build.lib.server.FailureDetails.SymlinkAction;
import com.google.devtools.build.lib.server.FailureDetails.SymlinkAction.Code;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
import com.google.devtools.build.lib.util.DetailedExitCode;
import com.google.devtools.build.lib.util.Fingerprint;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.io.IOException;

/**
 * Creates mangled symlinks in the solib directory for all shared libraries. Libraries that have a
 * potential to contain SONAME field rely on the mangled symlink to the parent directory instead.
 *
 * <p>Such symlinks are used by the linker to ensure that all rpath entries can be specified
 * relative to the $ORIGIN.
 */
@AutoCodec
@Immutable
public final class SolibSymlinkAction extends AbstractAction {
  private final Artifact symlink;

  @VisibleForSerialization
  SolibSymlinkAction(
      ActionOwner owner, Artifact primaryInput, Artifact primaryOutput) {
    super(
        owner,
        NestedSetBuilder.create(Order.STABLE_ORDER, primaryInput),
        ImmutableSet.of(primaryOutput));

    Preconditions.checkArgument(Link.SHARED_LIBRARY_FILETYPES.matches(primaryInput.getFilename()));
    this.symlink = Preconditions.checkNotNull(primaryOutput);
  }

  @Override
  public ActionResult execute(ActionExecutionContext actionExecutionContext)
      throws ActionExecutionException {
    Path mangledPath = actionExecutionContext.getInputPath(symlink);
    try {
      mangledPath.createSymbolicLink(actionExecutionContext.getInputPath(getPrimaryInput()));
    } catch (IOException e) {
      String message =
          String.format(
              "failed to create _solib symbolic link '%s' to target '%s': %s",
              symlink.prettyPrint(), getPrimaryInput(), e.getMessage());
      DetailedExitCode code =
          DetailedExitCode.of(
              FailureDetail.newBuilder()
                  .setMessage(message)
                  .setSymlinkAction(
                      SymlinkAction.newBuilder().setCode(Code.LINK_CREATION_IO_EXCEPTION))
                  .build());
      throw new ActionExecutionException(message, e, this, false, code);
    }
    return ActionResult.EMPTY;
  }

  @Override
  protected void computeKey(ActionKeyContext actionKeyContext, Fingerprint fp) {
    fp.addPath(symlink.getExecPath());
    fp.addPath(getPrimaryInput().getExecPath());
  }

  @Override
  public String getMnemonic() {
    return "SolibSymlink";
  }

  @Override
  protected String getRawProgressMessage() {
    return null;
  }

  /**
   * Replaces shared library artifact with mangled symlink and creates related symlink action. For
   * artifacts that should retain filename (e.g. libraries with SONAME tag), link is created to the
   * parent directory instead.
   *
   * <p>This action is performed to minimize number of -rpath entries used during linking process
   * (by essentially "collecting" as many shared libraries as possible in the single directory),
   * since we will be paying quadratic price for each additional entry on the -rpath.
   *
   * @param actionRegistry action registry of rule requesting symlink.
   * @param actionConstructionContext action construction context of rule requesting symlink
   * @param solibDir String giving the solib directory
   * @param library Shared library artifact that needs to be mangled.
   * @param preserveName whether to preserve the name of the library
   * @param prefixConsumer whether to prefix the output artifact name with the label of the consumer
   * @return mangled symlink artifact.
   */
  public static Artifact getDynamicLibrarySymlink(
      ActionRegistry actionRegistry,
      ActionConstructionContext actionConstructionContext,
      String solibDir,
      final Artifact library,
      boolean preserveName,
      boolean prefixConsumer) {
    PathFragment mangledName =
        getMangledName(
            actionRegistry.getOwner().getLabel(),
            solibDir,
            library.getRootRelativePath(),
            preserveName,
            prefixConsumer);
    return getDynamicLibrarySymlinkInternal(
        actionRegistry, actionConstructionContext, library, mangledName);
  }

  /**
   * Replaces shared library artifact with user specified symlink and creates related symlink
   * action.
   *
   * <p>This action is performed to minimize number of -rpath entries used during linking process
   * (by essentially "collecting" as many shared libraries as possible in the single directory),
   * since we will be paying quadratic price for each additional entry on the -rpath.
   *
   * @param actionRegistry action registry of rule requesting symlink.
   * @param actionConstructionContext action construction context of rule requesting symlink
   * @param solibDir String giving the solib directory
   * @param library Shared library artifact that needs to be linked.
   * @param path Symlink path underneath the solib directory.
   * @return linked symlink artifact.
   */
  public static Artifact getDynamicLibrarySymlink(
      ActionRegistry actionRegistry,
      ActionConstructionContext actionConstructionContext,
      String solibDir,
      final Artifact library,
      PathFragment path) {
    Preconditions.checkArgument(Link.SHARED_LIBRARY_FILETYPES.matches(library.getFilename()));
    Preconditions.checkArgument(Link.SHARED_LIBRARY_FILETYPES.matches(path.getBaseName()));
    Preconditions.checkArgument(!library.getRootRelativePath().getSegment(0).startsWith("_solib_"));

    PathFragment solibDirPath = PathFragment.create(solibDir);
    PathFragment linkName = solibDirPath.getRelative(path);
    return getDynamicLibrarySymlinkInternal(
        actionRegistry, actionConstructionContext, library, linkName);
  }

  /**
   * Version of {@link #getDynamicLibrarySymlink} for the special case of C++ runtime libraries.
   * These are handled differently than other libraries: neither their names nor directories are
   * mangled, i.e. libstdc++.so.6 is symlinked from _solib_[arch]/libstdc++.so.6
   */
  public static Artifact getCppRuntimeSymlink(
      RuleContext ruleContext,
      Artifact library,
      String toolchainProvidedSolibDir,
      String solibDirOverride) {
    PathFragment solibDir =
        PathFragment.create(
            solibDirOverride != null ? solibDirOverride : toolchainProvidedSolibDir);
    PathFragment symlinkName = solibDir.getRelative(library.getRootRelativePath().getBaseName());
    return getDynamicLibrarySymlinkInternal(
        /* actionRegistry= */ ruleContext,
        /* actionConstructionContext= */ ruleContext,
        library,
        symlinkName);
  }

  /**
   * Internal implementation that takes a pre-determined symlink name; supports both the generic
   * {@link #getDynamicLibrarySymlink} and the specialized {@link #getCppRuntimeSymlink}.
   */
  private static Artifact getDynamicLibrarySymlinkInternal(
      ActionRegistry actionRegistry,
      ActionConstructionContext actionConstructionContext,
      Artifact library,
      PathFragment symlinkName) {
    Preconditions.checkArgument(Link.SHARED_LIBRARY_FILETYPES.matches(library.getFilename()));
    Preconditions.checkArgument(!library.getRootRelativePath().getSegment(0).startsWith("_solib_"));

    // Ignore libraries that are already represented by the symlinks.
    ArtifactRoot root = actionConstructionContext.getBinDirectory();
    Artifact symlink = actionConstructionContext.getShareableArtifact(symlinkName, root);
    actionRegistry.registerAction(
        new SolibSymlinkAction(actionConstructionContext.getActionOwner(), library, symlink));
    return symlink;
  }

  /**
   * Returns the name of the symlink that will be created for a library, given its name.
   *
   * @param label label of the rule calling this
   * @param solibDir a String giving the solib directory
   * @param libraryPath the root-relative path of the library
   * @param preserveName true if filename should be preserved
   * @param prefixConsumer true if the result should be prefixed with the label of the consumer
   * @returns root relative path name
   */
  private static PathFragment getMangledName(
      Label label,
      String solibDir,
      PathFragment libraryPath,
      boolean preserveName,
      boolean prefixConsumer) {
    String escapedRulePath = Actions.escapedPath("_" + label);
    String soname = getDynamicLibrarySoname(libraryPath, preserveName);
    PathFragment solibDirPath = PathFragment.create(solibDir);
    if (preserveName) {
      String escapedLibraryPath =
          Actions.escapedPath("_" + libraryPath.getParentDirectory().getPathString());
      PathFragment mangledDir =
          solibDirPath.getRelative(
              prefixConsumer ? escapedRulePath + "__" + escapedLibraryPath : escapedLibraryPath);
      return mangledDir.getRelative(soname);
    } else {
      return solibDirPath.getRelative(prefixConsumer ? escapedRulePath + "__" + soname : soname);
    }
  }

  /**
   * Compute the SONAME to use for a dynamic library. This name is basically the
   * name of the shared library in its final symlinked location.
   *
   * @param libraryPath name of the shared library that needs to be mangled
   * @param preserveName true if filename should be preserved, false - mangled
   * @return soname to embed in the dynamic library
   */
  public static String getDynamicLibrarySoname(PathFragment libraryPath,
                                               boolean preserveName) {
    String mangledName;
    if (preserveName) {
      mangledName = libraryPath.getBaseName();
    } else {
      mangledName = "lib" + Actions.escapedPath(libraryPath.getPathString());
    }
    return mangledName;
  }

  @Override
  public boolean shouldReportPathPrefixConflict(ActionAnalysisMetadata action) {
    return false; // Always ignore path prefix conflict for the SolibSymlinkAction.
  }

  @Override
  public boolean mayInsensitivelyPropagateInputs() {
    return true;
  }
}
