// 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.ImmutableList;
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.concurrent.ThreadSafety.Immutable;
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.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, ImmutableList.of(primaryInput), ImmutableList.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) {
      throw new ActionExecutionException(
          "failed to create _solib symbolic link '"
              + symlink.prettyPrint()
              + "' to target '"
              + getPrimaryInput()
              + "': "
              + e.getMessage(),
          e,
          this,
          false);
    }
    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);
  }

  /**
   * 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;
  }
}
