// 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.packages.Type;
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.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.PathFragment;
import net.starlark.java.annot.StarlarkMethod;
import net.starlark.java.eval.StarlarkValue;

/** 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 implements StarlarkValue {
  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. */
  @StarlarkMethod(name = "archive_file_name_suffix", documented = false, structField = true)
  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.
   */
  @StarlarkMethod(name = "archive_obj_list", documented = false, structField = true)
  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(String childCpu) {
    return appendExtension("-" + childCpu + "-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. */
  @StarlarkMethod(name = "combined_architecture_archive", documented = false, structField = true)
  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)));
  }

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

  private String getModuleName() {
    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(":", "_");
    }
    return moduleName;
  }

  /** {@link CppModuleMap} for swift. */
  @StarlarkMethod(name = "swift_module_map", documented = false, structField = true)
  public CppModuleMap swiftModuleMap() {
    String moduleName = getModuleName();
    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);
    }
  }

  /** {@link CppModuleMap} for layering check and modules. */
  @StarlarkMethod(name = "internal_module_map", documented = false, structField = true)
  public CppModuleMap internalModuleMap() {
    return new CppModuleMap(appendExtensionInGenfiles(".internal.cppmap"), getModuleName());
  }

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