// 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.BuildConfigurationValue;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.BuiltinRestriction;
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.PathFragment;
import net.starlark.java.annot.StarlarkMethod;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.StarlarkThread;
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 BuildConfigurationValue buildConfiguration;
  private final String archiveFileNameSuffix;
  private final UmbrellaHeaderStrategy umbrellaHeaderStrategy;
  private final AlwaysLink alwaysLink;

  /** How to determine whether the archive is alwaysLink. */
  public enum AlwaysLink {
    FROM_ATTRIBUTE,
    TRUE,
    FALSE
  };

  IntermediateArtifacts(RuleContext ruleContext) {
    this(
        ruleContext,
        /* archiveFileNameSuffix= */ "",
        ruleContext.getConfiguration(),
        UmbrellaHeaderStrategy.DO_NOT_GENERATE,
        AlwaysLink.FROM_ATTRIBUTE);
  }

  IntermediateArtifacts(RuleContext ruleContext, BuildConfigurationValue buildConfiguration) {
    this(
        ruleContext,
        /* archiveFileNameSuffix= */ "",
        buildConfiguration,
        UmbrellaHeaderStrategy.DO_NOT_GENERATE,
        AlwaysLink.FROM_ATTRIBUTE);
  }

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

  IntermediateArtifacts(
      RuleContext ruleContext,
      String archiveFileNameSuffix,
      BuildConfigurationValue buildConfiguration,
      UmbrellaHeaderStrategy umbrellaHeaderStrategy,
      AlwaysLink alwaysLink) {
    this.ruleContext = ruleContext;
    this.buildConfiguration = buildConfiguration;
    this.archiveFileNameSuffix = Preconditions.checkNotNull(archiveFileNameSuffix);
    this.umbrellaHeaderStrategy = umbrellaHeaderStrategy;
    this.alwaysLink = alwaysLink;
  }

  /** 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(join(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(join(name.getBaseName(), extension)), /* inGenfiles= */ true);
  }

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


  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 archive file which contains all the compiled sources for a rule. */
  public Artifact archive() {
    // The path will be {RULE_PACKAGE}/lib{RULEBASENAME}{.a,.lo,{SUFFIX}.a}
    String basename = PathFragment.create(ruleContext.getLabel().getName()).getBaseName();
    String extension;
    AttributeMap attributes = ruleContext.attributes();
    ObjcConfiguration objcConfiguration = buildConfiguration.getFragment(ObjcConfiguration.class);

    switch (alwaysLink) {
      case FROM_ATTRIBUTE:
        Preconditions.checkState(attributes.has("alwayslink", Type.BOOLEAN));
        if (attributes.isAttributeValueExplicitlySpecified("alwayslink")
            ? attributes.get("alwayslink", Type.BOOLEAN)
            : objcConfiguration.alwayslinkByDefault()) {
          extension = ".lo";
        } else {
          extension = ".a";
        }
        break;
      case TRUE:
        extension = ".lo";
        break;
      case FALSE:
      default:
        extension = ".a";
        break;
    }

    return scopedArtifact(
        PathFragment.create(
            String.format("lib%s%s%s", basename, archiveFileNameSuffix, extension)));
  }

  @StarlarkMethod(name = "archive", documented = false, useStarlarkThread = true)
  public Artifact archiveForStarlark(StarlarkThread thread) throws EvalException {
    BuiltinRestriction.failIfCalledOutsideBuiltins(thread);
    return archive();
  }

  /** 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"), ruleContext.getLabel().toString());
  }

  /** Returns baseName appeneded with extension. */
  private static String join(String baseName, String extension) {
    return String.format("%s%s", baseName, extension);
  }
}
