// Copyright 2015 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 static com.google.devtools.build.lib.packages.ImplicitOutputsFunction.fromTemplates;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.google.common.io.ByteSource;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.actions.BinaryFileWriteAction;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.analysis.actions.SymlinkAction;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction;
import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
import com.google.devtools.build.lib.rules.apple.AppleConfiguration.ConfigurationDistinguisher;
import com.google.devtools.build.lib.rules.objc.XcodeProvider.Builder;
import com.google.devtools.build.lib.rules.objc.XcodeProvider.Project;
import com.google.devtools.build.xcode.xcodegen.proto.XcodeGenProtos;
import com.google.devtools.build.xcode.xcodegen.proto.XcodeGenProtos.XcodeprojBuildSetting;

import java.io.InputStream;
import java.util.List;

/**
 * Support for Objc rule types that export an Xcode provider or generate xcode project files.
 *
 * <p>Methods on this class can be called in any order without impacting the result.
 *
 * <p>These objects should not outlast the analysis phase. Do not pass them to {@link Action}
 * objects or other persistent objects. There are internal tests to ensure that XcodeSupport objects
 * are not persisted that check the name of this class, so update those tests if you change this
 * class's name.
 */
public final class XcodeSupport {

  /**
   * Template for a target's xcode project.
   */
  public static final SafeImplicitOutputsFunction PBXPROJ =
      fromTemplates("%{name}.xcodeproj/project.pbxproj");

  private final RuleContext ruleContext;
  private final IntermediateArtifacts intermediateArtifacts;
  private final Label xcodeTargetLabel;

  /**
   * Creates a new xcode support for the given context.
   */
  XcodeSupport(RuleContext ruleContext)  {
    this(ruleContext, ObjcRuleClasses.intermediateArtifacts(ruleContext), ruleContext.getLabel());
  }

  /**
   * Creates a new xcode support for the given context and {@link IntermediateArtifacts} with given
   * target label.
   */
  public XcodeSupport(
      RuleContext ruleContext, IntermediateArtifacts intermediateArtifacts,
      Label xcodeTargetLabel) {
    this.ruleContext = ruleContext;
    this.intermediateArtifacts = intermediateArtifacts;
    this.xcodeTargetLabel = xcodeTargetLabel;
  }

  /**
   * Adds xcode project files to the given builder.
   *
   * @return this xcode support
   * @throws InterruptedException 
   */
  XcodeSupport addFilesToBuild(NestedSetBuilder<Artifact> filesToBuild)
      throws InterruptedException {
    filesToBuild.add(ruleContext.getImplicitOutputArtifact(PBXPROJ));
    return this;
  }

  /**
   * Adds a dummy source file to the Xcode target. This is needed if the target does not have any
   * source files but Xcode requires one.
   *
   * @return this xcode support
   */
  XcodeSupport addDummySource(XcodeProvider.Builder xcodeProviderBuilder) {
    ruleContext.registerAction(new SymlinkAction(
        ruleContext.getActionOwner(),
        ruleContext.getPrerequisiteArtifact("$dummy_source", Mode.TARGET),
        intermediateArtifacts.dummySource(),
        "Symlinking dummy artifact"));

    xcodeProviderBuilder.addAdditionalSources(intermediateArtifacts.dummySource());
    return this;
  }

  /**
   * Registers actions that generate the rule's Xcode project.
   *
   * @param xcodeProvider information about this rule's xcode settings and that of its dependencies
   * @return this xcode support
   * @throws InterruptedException 
   */
  XcodeSupport registerActions(XcodeProvider xcodeProvider) throws InterruptedException {
    registerXcodegenActions(XcodeProvider.Project.fromTopLevelTarget(xcodeProvider));
    return this;
  }

  /**
   * Registers actions that generate the rule's Xcode project.
   *
   * @param xcodeProviders information about several rules' xcode settings
   * @return this xcode support
   * @throws InterruptedException 
   */
  XcodeSupport registerActions(Iterable<XcodeProvider> xcodeProviders) throws InterruptedException {
    registerXcodegenActions(Project.fromTopLevelTargets(xcodeProviders));
    return this;
  }

  /**
   * Adds common xcode settings to the given provider builder.
   *
   * @param objcProvider provider containing all dependencies' information as well as some of this
   *    rule's
   * @param productType type of this rule's Xcode target
   *
   * @return this xcode support
   */
  XcodeSupport addXcodeSettings(XcodeProvider.Builder xcodeProviderBuilder,
      ObjcProvider objcProvider, XcodeProductType productType) {
    AppleConfiguration appleConfiguration = ruleContext.getFragment(AppleConfiguration.class);
    return addXcodeSettings(xcodeProviderBuilder, objcProvider, productType,
        appleConfiguration.getIosCpu(), appleConfiguration.getConfigurationDistinguisher());
  }

  /**
   * Adds common xcode settings to the given provider builder, explicitly specifying architecture
   * to use.
   *
   * @param objcProvider provider containing all dependencies' information as well as some of this
   *    rule's
   * @param productType type of this rule's Xcode target
   * @param architecture architecture to filter all dependencies with (only matching ones will be
   *    included in the final targets generated)
   * @param configurationDistinguisher distinguisher that will cause this target's xcode provider to
   *    discard any dependencies from sources that are tagged with a different distinguisher
   * @return this xcode support
   */
  XcodeSupport addXcodeSettings(Builder xcodeProviderBuilder,
      ObjcProvider objcProvider, XcodeProductType productType, String architecture,
      ConfigurationDistinguisher configurationDistinguisher) {
    xcodeProviderBuilder
        .setLabel(xcodeTargetLabel)
        .setArchitecture(architecture)
        .setConfigurationDistinguisher(configurationDistinguisher)
        .setObjcProvider(objcProvider)
        .setProductType(productType)
        .addXcodeprojBuildSettings(XcodeSupport.defaultXcodeSettings());
    return this;
  }

  /**
   * Adds dependencies to the given provider builder from the given attribute.
   *
   * @return this xcode support
   */
  XcodeSupport addDependencies(Builder xcodeProviderBuilder, Attribute attribute) {
    xcodeProviderBuilder.addPropagatedDependencies(
        ruleContext.getPrerequisites(
            attribute.getName(), attribute.getAccessMode(), XcodeProvider.class));
    return this;
  }

  /**
   * Adds non-propagated dependencies to the given provider builder from the given attribute.
   *
   * <p>A non-propagated dependency will not be linked into the final app bundle and can only serve
   * as a compile-only dependency for its direct dependent.
   *
   * @return this xcode support
   */
  XcodeSupport addNonPropagatedDependencies(Builder xcodeProviderBuilder, Attribute attribute) {
    xcodeProviderBuilder.addNonPropagatedDependencies(
        ruleContext.getPrerequisites(
            attribute.getName(), attribute.getAccessMode(), XcodeProvider.class));
    return this;
  }

  /**
   * Adds J2ObjC JRE dependencies to the given provider builder from the given attribute.
   *
   * @return this xcode support
   */
  XcodeSupport addJreDependencies(Builder xcodeProviderBuilder) {
    xcodeProviderBuilder.addJreDependencies(
        ruleContext.getPrerequisites("jre_deps", Mode.TARGET, XcodeProvider.class));
    return this;
  }

  /**
   * Generates an extra {@link XcodeProductType#LIBRARY_STATIC} Xcode target with the same
   * compilation artifacts as the main Xcode target associated with this Xcode support. The extra
   * Xcode library target, instead of the main Xcode target, will act as a dependency for all
   * dependent Xcode targets.
   *
   * <p>This is needed to build the Xcode binary target generated by ios_application in XCode.
   * Currently there is an Xcode target dependency between the binary target from ios_application
   * and the binary target from objc_binary. But Xcode does not link in compiled artifacts from
   * binary dependencies, so any sources specified on objc_binary rules will not be compiled and
   * linked into the app bundle in dependent binary targets associated with ios_application in
   * XCode.
   */
  // TODO(bazel-team): Remove this when the binary rule types and bundling rule types are merged.
  XcodeSupport generateCompanionLibXcodeTarget(Builder xcodeProviderBuilder) {
    xcodeProviderBuilder.generateCompanionLibTarget();
    return this;
  }

  private void registerXcodegenActions(XcodeProvider.Project project) throws InterruptedException {
    Artifact controlFile = intermediateArtifacts.pbxprojControlArtifact();

    ruleContext.registerAction(new BinaryFileWriteAction(
        ruleContext.getActionOwner(),
        controlFile,
        xcodegenControlFileBytes(project),
        /*makeExecutable=*/false));

    ruleContext.registerAction(new SpawnAction.Builder()
        .setMnemonic("GenerateXcodeproj")
        .setExecutable(ruleContext.getExecutablePrerequisite("$xcodegen", Mode.HOST))
        .addArgument("--control")
        .addInputArgument(controlFile)
        .addOutput(ruleContext.getImplicitOutputArtifact(XcodeSupport.PBXPROJ))
        .addTransitiveInputs(project.getInputsToXcodegen())
        .addTransitiveInputs(project.getAdditionalSources())
        .build(ruleContext));
  }

  /**
   * Static class to avoid keeping references to configurations and this XcodeSupport object during
   * execution.
   */
  private static class XcodegenControlFileBytes extends ByteSource {
    private final XcodeProvider.Project project;
    private final Artifact pbxproj;
    private final String workspaceRoot;
    private final List<String> appleCpus;
    private final String minimumOs;
    private final boolean generateDebugSymbols;

    XcodegenControlFileBytes(
        ObjcConfiguration objcConfiguration,
        AppleConfiguration appleConfiguration,
        Project project,
        Artifact pbxproj) {
      this.project = project;
      this.pbxproj = pbxproj;
      this.workspaceRoot = objcConfiguration.getXcodeWorkspaceRoot();
      this.appleCpus = appleConfiguration.getMultiArchitectures(
          appleConfiguration.getSingleArchPlatform().getType());
      this.minimumOs = objcConfiguration.getMinimumOs().toString();
      this.generateDebugSymbols = objcConfiguration.generateDsym();
    }

    @Override
    public InputStream openStream() {
      XcodeGenProtos.Control.Builder builder = XcodeGenProtos.Control.newBuilder();
      if (workspaceRoot != null) {
        builder.setWorkspaceRoot(workspaceRoot);
      }

      builder.addAllCpuArchitecture(appleCpus);

      return builder
          .setPbxproj(pbxproj.getExecPathString())
          .addAllTarget(project.targets())
          .addBuildSetting(
              XcodeGenProtos.XcodeprojBuildSetting.newBuilder()
                  .setName("IPHONEOS_DEPLOYMENT_TARGET")
                  .setValue(minimumOs)
                  .build())
          .addBuildSetting(
              XcodeGenProtos.XcodeprojBuildSetting.newBuilder()
                  .setName("DEBUG_INFORMATION_FORMAT")
                  .setValue(generateDebugSymbols ? "dwarf-with-dsym" : "dwarf")
                  .build())
          .build()
          .toByteString()
          .newInput();
    }
  }

  private ByteSource xcodegenControlFileBytes(XcodeProvider.Project project)
      throws InterruptedException {
    return new XcodegenControlFileBytes(
        ObjcRuleClasses.objcConfiguration(ruleContext),
        ruleContext.getFragment(AppleConfiguration.class),
        project,
        ruleContext.getImplicitOutputArtifact(XcodeSupport.PBXPROJ));
  }

  /**
   * Returns a list of default XCode build settings for Bazel-generated XCode projects.
   */
  @VisibleForTesting
  static Iterable<XcodeprojBuildSetting> defaultXcodeSettings() {
    // Do not use XCode headermap because Bazel-generated header search paths are sufficient for
    // resolving header imports.
    return ImmutableList.of(
        XcodeprojBuildSetting.newBuilder()
            .setName("USE_HEADERMAP")
            .setValue("NO")
            .build());
  }
}
