// Copyright 2016 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.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException;
import com.google.devtools.build.lib.analysis.OutputGroupInfo;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.rules.apple.AppleCommandLineOptions.AppleBitcodeMode;
import com.google.devtools.build.lib.rules.cpp.CcInfo;
import com.google.devtools.build.lib.rules.cpp.CppConfiguration;
import com.google.devtools.build.lib.rules.cpp.CppSemantics;
import com.google.devtools.build.lib.rules.objc.AppleDebugOutputsInfo.OutputType;
import com.google.devtools.build.lib.rules.objc.AppleLinkingOutputs.TargetTriplet;
import com.google.devtools.build.lib.rules.objc.CompilationSupport.ExtraLinkArgs;
import com.google.devtools.build.lib.rules.objc.MultiArchBinarySupport.DependencySpecificConfiguration;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/** Native support for Apple binary rules. */
public class AppleBinary {
  private AppleBinary() {}

  /**
   * Links a (potentially multi-architecture) binary targeting Apple platforms.
   *
   * <p>This method comprises a bulk of the logic of the {@code apple_binary} rule, and is
   * statically available so that it may be referenced by Starlark APIs that replicate its
   * functionality.
   *
   * @param ruleContext the current rule context
   * @param cppSemantics the cpp semantics to use
   * @param avoidDeps a list of {@code TransitiveInfoColllection} that contain information about
   *     dependencies whose symbols are used by the linked binary but should not be linked into the
   *     binary itself
   * @param extraLinkopts extra linkopts to pass to the linker actions
   * @param extraLinkInputs extra input files to pass to the linker action
   * @param isStampingEnabled whether linkstamping is enabled
   * @return a tuple containing all necessary information about the linked binary
   */
  public static AppleLinkingOutputs linkMultiArchBinary(
      RuleContext ruleContext,
      CppSemantics cppSemantics,
      ImmutableList<TransitiveInfoCollection> avoidDeps,
      Iterable<String> extraLinkopts,
      Iterable<Artifact> extraLinkInputs,
      boolean isStampingEnabled)
      throws InterruptedException, RuleErrorException, ActionConflictException {
    Map<Optional<String>, List<ConfiguredTargetAndData>> splitDeps =
        ruleContext.getSplitPrerequisiteConfiguredTargetAndTargets("deps");
    Map<Optional<String>, List<ConfiguredTargetAndData>> splitToolchains =
        ruleContext.getSplitPrerequisiteConfiguredTargetAndTargets(
            ObjcRuleClasses.CHILD_CONFIG_ATTR);

    Preconditions.checkState(
        splitDeps.keySet().isEmpty() || splitDeps.keySet().equals(splitToolchains.keySet()),
        "Split transition keys are different between 'deps' [%s] and '%s' [%s]",
        splitDeps.keySet(),
        ObjcRuleClasses.CHILD_CONFIG_ATTR,
        splitToolchains.keySet());

    MultiArchBinarySupport multiArchBinarySupport =
        new MultiArchBinarySupport(ruleContext, cppSemantics);
    ImmutableMap<Optional<String>, DependencySpecificConfiguration>
        dependencySpecificConfigurations =
            multiArchBinarySupport.getDependencySpecificConfigurations(
                splitToolchains, splitDeps, avoidDeps);

    Map<String, NestedSet<Artifact>> outputGroupCollector = new TreeMap<>();

    ImmutableList.Builder<Artifact> allLinkInputs = ImmutableList.builder();
    ImmutableList.Builder<String> allLinkopts = ImmutableList.builder();
    allLinkInputs.addAll(extraLinkInputs);
    allLinkopts.addAll(extraLinkopts);

    ImmutableListMultimap<BuildConfigurationValue, CcInfo> buildConfigToCcInfoMap =
        ruleContext.getPrerequisitesByConfiguration("deps", CcInfo.PROVIDER);
    NestedSetBuilder<Artifact> headerTokens = NestedSetBuilder.stableOrder();
    for (Map.Entry<BuildConfigurationValue, CcInfo> entry : buildConfigToCcInfoMap.entries()) {
      CcInfo dep = entry.getValue();
      headerTokens.addTransitive(dep.getCcCompilationContext().getHeaderTokens());
    }
    outputGroupCollector.put(OutputGroupInfo.VALIDATION, headerTokens.build());

    ObjcProvider.Builder objcProviderBuilder =
        new ObjcProvider.Builder(ruleContext.getAnalysisEnvironment().getStarlarkSemantics());
    ImmutableList.Builder<CcInfo> ccInfos = new ImmutableList.Builder<>();
    for (DependencySpecificConfiguration dependencySpecificConfiguration :
        dependencySpecificConfigurations.values()) {
      objcProviderBuilder.addTransitiveAndPropagate(
          dependencySpecificConfiguration.objcProviderWithAvoidDepsSymbols());
      ccInfos.add(dependencySpecificConfiguration.ccInfoWithAvoidDepsSymbols());
    }
    CcInfo ccInfo = CcInfo.merge(ccInfos.build());

    AppleDebugOutputsInfo.Builder legacyDebugOutputsBuilder =
        AppleDebugOutputsInfo.Builder.create();
    AppleLinkingOutputs.Builder builder =
        new AppleLinkingOutputs.Builder().addOutputGroups(outputGroupCollector);

    for (Optional<String> splitTransitionKey : dependencySpecificConfigurations.keySet()) {
      DependencySpecificConfiguration dependencySpecificConfiguration =
          dependencySpecificConfigurations.get(splitTransitionKey);
      BuildConfigurationValue childConfig = dependencySpecificConfiguration.config();
      CppConfiguration childCppConfig = childConfig.getFragment(CppConfiguration.class);
      IntermediateArtifacts intermediateArtifacts =
          new IntermediateArtifacts(ruleContext, childConfig);

      List<? extends TransitiveInfoCollection> propagatedDeps =
          MultiArchBinarySupport.getProvidersFromCtads(splitDeps.get(splitTransitionKey));

      Artifact binaryArtifact =
          multiArchBinarySupport.registerConfigurationSpecificLinkActions(
              dependencySpecificConfiguration,
              new ExtraLinkArgs(allLinkopts.build()),
              allLinkInputs.build(),
              isStampingEnabled,
              propagatedDeps,
              outputGroupCollector);

      TargetTriplet childTriplet = MultiArchBinarySupport.getTargetTriplet(childConfig);
      AppleLinkingOutputs.LinkingOutput.Builder outputBuilder =
          AppleLinkingOutputs.LinkingOutput.builder()
              .setTargetTriplet(childTriplet)
              .setBinary(binaryArtifact);

      if (childCppConfig.getAppleBitcodeMode() == AppleBitcodeMode.EMBEDDED) {
        Artifact bitcodeSymbols = intermediateArtifacts.bitcodeSymbolMap();
        outputBuilder.setBitcodeSymbols(bitcodeSymbols);
        legacyDebugOutputsBuilder.addOutput(
            childTriplet.architecture(), OutputType.BITCODE_SYMBOLS, bitcodeSymbols);
      }
      if (childCppConfig.appleGenerateDsym()) {
        Artifact dsymBinary =
            childCppConfig.objcShouldStripBinary()
                ? intermediateArtifacts.dsymSymbolForUnstrippedBinary()
                : intermediateArtifacts.dsymSymbolForStrippedBinary();
        outputBuilder.setDsymBinary(dsymBinary);
        legacyDebugOutputsBuilder.addOutput(
            childTriplet.architecture(), OutputType.DSYM_BINARY, dsymBinary);
      }
      if (childCppConfig.objcGenerateLinkmap()) {
        Artifact linkmap = intermediateArtifacts.linkmap();
        outputBuilder.setLinkmap(linkmap);
        legacyDebugOutputsBuilder.addOutput(
            childTriplet.architecture(), OutputType.LINKMAP, linkmap);
      }

      builder.addOutput(outputBuilder.build());
    }

    return builder
        .setDepsObjcProvider(objcProviderBuilder.build())
        .setDepsCcInfo(ccInfo)
        .setLegacyDebugOutputsProvider(legacyDebugOutputsBuilder.build())
        .build();
  }
}
