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

import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
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.config.BuildConfiguration;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.rules.cpp.CppModuleMap;
import com.google.devtools.build.lib.rules.cpp.CppModuleMap.UmbrellaHeaderStrategy;
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.PathFragment;

/**
 * Factory class for generating artifacts which are used as intermediate output.
 */
// TODO(bazel-team): This should really be named DerivedArtifacts as it contains methods for
// final as well as intermediate artifacts.
public final class IntermediateArtifacts {
  static final String LINKMAP_SUFFIX = ".linkmap";

  private final RuleContext ruleContext;
  private final BuildConfiguration buildConfiguration;
  private final String archiveFileNameSuffix;
  private final String outputPrefix;
  private final UmbrellaHeaderStrategy umbrellaHeaderStrategy;

  IntermediateArtifacts(RuleContext ruleContext, String archiveFileNameSuffix,
      String outputPrefix) {
    this(ruleContext, archiveFileNameSuffix, outputPrefix, ruleContext.getConfiguration(),
        UmbrellaHeaderStrategy.DO_NOT_GENERATE);
  }

  IntermediateArtifacts(RuleContext ruleContext, String archiveFileNameSuffix) {
    this(ruleContext, archiveFileNameSuffix, "", ruleContext.getConfiguration(),
        UmbrellaHeaderStrategy.DO_NOT_GENERATE);
  }

  IntermediateArtifacts(RuleContext ruleContext, String archiveFileNameSuffix,
      UmbrellaHeaderStrategy umbrellaHeaderStrategy) {
    this(ruleContext, archiveFileNameSuffix, "", ruleContext.getConfiguration(),
        umbrellaHeaderStrategy);
  }

  IntermediateArtifacts(RuleContext ruleContext, String archiveFileNameSuffix, String outputPrefix,
      BuildConfiguration buildConfiguration) {
    this(ruleContext, archiveFileNameSuffix, outputPrefix, buildConfiguration,
        UmbrellaHeaderStrategy.DO_NOT_GENERATE);
  }

  IntermediateArtifacts(RuleContext ruleContext, String archiveFileNameSuffix, String outputPrefix,
      BuildConfiguration buildConfiguration, UmbrellaHeaderStrategy umbrellaHeaderStrategy) {
    this.ruleContext = ruleContext;
    this.buildConfiguration = buildConfiguration;
    this.archiveFileNameSuffix = Preconditions.checkNotNull(archiveFileNameSuffix);
    this.outputPrefix = Preconditions.checkNotNull(outputPrefix);
    this.umbrellaHeaderStrategy = umbrellaHeaderStrategy;
  }

  /**
   * Returns the archive file name suffix.
   */
  public String archiveFileNameSuffix() {
    return archiveFileNameSuffix;
  }

  /**
   * Returns a derived artifact in the bin directory obtained by appending some extension to the end
   * of the {@link PathFragment} corresponding to the owner {@link Label}.
   */
  private Artifact appendExtension(String extension) {
    PathFragment name = PathFragment.create(ruleContext.getLabel().getName());
    return scopedArtifact(name.replaceName(addOutputPrefix(name.getBaseName(), extension)));
  }

  /**
   * Returns a derived artifact in the genfiles directory obtained by appending some extension to
   * the end of the {@link PathFragment} corresponding to the owner {@link Label}.
   */
  private Artifact appendExtensionInGenfiles(String extension) {
    PathFragment name = PathFragment.create(ruleContext.getLabel().getName());
    return scopedArtifact(
        name.replaceName(addOutputPrefix(name.getBaseName(), extension)), /* inGenfiles = */ true);
  }

  /**
   * The .objlist file, which contains a list of paths of object files to archive and is read by
   * clang (via -filelist flag) in the link action (for binary creation).
   */
  public Artifact linkerObjList() {
    return appendExtension("-linker.objlist");
  }

  /**
   * The .objlist file, which contains a list of paths of object files to archive  and is read by
   * libtool (via -filelist flag) in the archive action.
   */
  public Artifact archiveObjList() {
    return appendExtension("-archive.objlist");
  }

  /**
   * The artifact which is the binary (or library) which is comprised of one or more .a files linked
   * together. Compared to the artifact returned by {@link #unstrippedSingleArchitectureBinary},
   * this artifact is stripped of symbol table when --compilation_mode=opt and
   * --objc_enable_binary_stripping are specified.
   */
  public Artifact strippedSingleArchitectureBinary() {
    return appendExtension("_bin");
  }

  /**
   * The artifact which is the fully-linked static library comprised of statically linking compiled
   * sources and dependencies together.
   */
  public Artifact strippedSingleArchitectureLibrary() {
    return appendExtension("-fl.a");
  }

  /**
   * The artifact which is the binary (or library) which is comprised of one or more .a files linked
   * together. It also contains full debug symbol information, compared to the artifact returned
   * by {@link #strippedSingleArchitectureBinary}. This artifact will serve as input for the symbol
   * strip action and is only created when --compilation_mode=opt and
   * --objc_enable_binary_stripping are specified.
   */
  public Artifact unstrippedSingleArchitectureBinary() {
    return appendExtension("_bin_unstripped");
  }

  /**
   * Lipo binary generated by combining one or more linked binaries. This binary is the one included
   * in generated bundles and invoked as entry point to the application.
   */
  public Artifact combinedArchitectureBinary() {
    return appendExtension("_lipobin");
  }

  /**
   * Lipo archive generated by combining one or more linked archives.
   */
  public Artifact combinedArchitectureArchive() {
    return appendExtension("_lipo.a");
  }

  /**
   * Lipo'ed dynamic library generated by combining one or more single-architecture linked dynamic
   * libraries.
   */
  public Artifact combinedArchitectureDylib() {
    return appendExtension("_lipo.dylib");
  }

  private Artifact scopedArtifact(PathFragment scopeRelative, boolean inGenfiles) {
    ArtifactRoot root =
        inGenfiles
            ? buildConfiguration.getGenfilesDirectory(ruleContext.getRule().getRepository())
            : buildConfiguration.getBinDirectory(ruleContext.getRule().getRepository());

    // The path of this artifact will be RULE_PACKAGE/SCOPERELATIVE
    return ruleContext.getPackageRelativeArtifact(scopeRelative, root);
  }

  private Artifact scopedArtifact(PathFragment scopeRelative) {
    return scopedArtifact(scopeRelative, /* inGenfiles = */ false);
  }

  /**
   * The {@code .a} file which contains all the compiled sources for a rule.
   */
  public Artifact archive() {
    // The path will be {RULE_PACKAGE}/lib{RULEBASENAME}{SUFFIX}.a
    String basename = PathFragment.create(ruleContext.getLabel().getName()).getBaseName();
    return scopedArtifact(PathFragment.create(String.format(
        "lib%s%s.a", basename, archiveFileNameSuffix)));
  }

  /** The artifact for the .headers file output by the header thinning action for this source. */
  public Artifact headersListFile(Artifact objectFile) {
    PathFragment headersListArtifactPath =
        FileSystemUtils.replaceExtension(objectFile.getRootRelativePath(), ".headers_list");
    return ruleContext.getUniqueDirectoryArtifact(
        "_header_lists",
        headersListArtifactPath,
        buildConfiguration.getBinDirectory(ruleContext.getRule().getRepository()));
  }

  /**
   * Debug symbol file generated for a stripped linked binary.
   *
   * <p>The name of the debug symbol file matches that of stripped binary plus that of the debug
   * symbol file extension (.dwarf), so we must know if the binary has been stripped
   * or not as that will modify its name.
   */
  public Artifact dsymSymbolForStrippedBinary() {
    return dsymSymbol("bin");
  }

  /**
   * Debug symbol file generated for an unstripped linked binary.
   *
   * <p>The name of the debug symbol file matches that of unstripped binary plus that of the debug
   * symbol file extension (.dwarf).
   */
  public Artifact dsymSymbolForUnstrippedBinary() {
    return dsymSymbol("bin_unstripped");
  }

  /**
   * Debug symbol file generated for a linked binary, for a specific architecture.
   */
  private Artifact dsymSymbol(String suffix) {
    return appendExtension(String.format("_%s.dwarf", suffix));
  }

  /** Bitcode symbol map generated for a linked binary, for a specific architecture. */
  public Artifact bitcodeSymbolMap() {
    return appendExtension(".bcsymbolmap");
  }

  /** Representation for a specific architecture. */
  private Artifact architectureRepresentation(String arch, String suffix) {
    return appendExtension(String.format("_%s%s", arch, suffix));
  }

  /**
   * Linkmap representation
   */
  public Artifact linkmap() {
    return appendExtension(LINKMAP_SUFFIX);
  }

  /**
   * Linkmap representation for a specific architecture.
   */
  public Artifact linkmap(String arch) {
    return architectureRepresentation(arch, LINKMAP_SUFFIX);
  }

  /**
   * {@link CppModuleMap} that provides the clang module map for this target.
   */
  public CppModuleMap moduleMap() {
    String moduleName;
    if (ruleContext.attributes().isAttributeValueExplicitlySpecified("module_name")) {
      moduleName = ruleContext.attributes().get("module_name", Type.STRING);
    } else {
      moduleName =
          ruleContext
              .getLabel()
              .toString()
              .replace("//", "")
              .replace("@", "")
              .replace("-", "_")
              .replace("/", "_")
              .replace(":", "_");
    }
    Optional<Artifact> customModuleMap = CompilationSupport.getCustomModuleMap(ruleContext);
    if (customModuleMap.isPresent()) {
      return new CppModuleMap(customModuleMap.get(), moduleName);
    } else if (umbrellaHeaderStrategy == UmbrellaHeaderStrategy.GENERATE) {
      // To get Swift to pick up module maps, we need to name them "module.modulemap" and have their
      // parent directory in the module map search paths.
      return new CppModuleMap(
          appendExtensionInGenfiles(".modulemaps/module.modulemap"),
          appendExtensionInGenfiles(".modulemaps/umbrella.h"),
          moduleName);
    } else {
      return new CppModuleMap(
          appendExtensionInGenfiles(".modulemaps/module.modulemap"), moduleName);
    }
  }

  /**
   * Returns a static library archive with dead code/objects removed by J2ObjC dead code removal,
   * given the original unpruned static library containing J2ObjC-translated code.
   */
  public Artifact j2objcPrunedArchive(Artifact unprunedArchive) {
    PathFragment prunedSourceArtifactPath = FileSystemUtils.appendWithoutExtension(
        unprunedArchive.getRootRelativePath(), "_pruned");
    return ruleContext.getUniqueDirectoryArtifact(
        "_j2objc_pruned",
        prunedSourceArtifactPath,
        buildConfiguration.getBinDirectory(ruleContext.getRule().getRepository()));
  }

  /**
   * Returns artifact name prefixed with an output prefix if specified.
   */
  private String addOutputPrefix(String baseName, String artifactName) {
    if (!outputPrefix.isEmpty()) {
      return String.format("%s-%s%s", baseName, outputPrefix, artifactName);
    }
    return String.format("%s%s", baseName, artifactName);
  }

}
