// 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 static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.BundlingRule.FAMILIES_ATTR;
import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.ReleaseBundlingRule.APP_ICON_ATTR;
import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.ReleaseBundlingRule.BUNDLE_ID_ATTR;
import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.ReleaseBundlingRule.DEFAULT_PROVISIONING_PROFILE_ATTR;
import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.ReleaseBundlingRule.LAUNCH_IMAGE_ATTR;
import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.ReleaseBundlingRule.LAUNCH_STORYBOARD_ATTR;
import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.ReleaseBundlingRule.PROVISIONING_PROFILE_ATTR;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
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.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.rules.objc.TargetDeviceFamily.InvalidFamilyNameException;
import com.google.devtools.build.lib.rules.objc.TargetDeviceFamily.RepeatedFamilyNameException;
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.util.Preconditions;

import java.util.List;

/**
 * Contains information regarding the creation of a released bundle such as an application
 * or extension. The information which generally includes app icons, launch image, targeted devices
 * and other data for potential signing is used to create a releasable bundle out of the bundle
 * created using {@link Bundling} object.
 */
@Immutable
final class ReleaseBundling {
  static final class Builder {
    private Artifact ipaArtifact;
    private String bundleId;
    private String primaryBundleId;
    private String fallbackBundleId;
    private String appIcon;
    private String launchImage;
    private Artifact launchStoryboard;
    private Artifact provisioningProfile;
    private String provisioningProfileAttributeName;
    private final NestedSetBuilder<Artifact> infoplistInputs = NestedSetBuilder.stableOrder();
    private Iterable<Artifact> infoPlistsFromRule;
    private ImmutableSet<TargetDeviceFamily> families;
    private IntermediateArtifacts intermediateArtifacts;
    private String artifactPrefix;
    private Artifact entitlements;
    private Artifact extraEntitlements;

    public Builder setIpaArtifact(Artifact ipaArtifact) {
      this.ipaArtifact = ipaArtifact;
      return this;
    }

    public Builder setBundleId(String bundleId) {
      this.bundleId = bundleId;
      return this;
    }

    public Builder setPrimaryBundleId(String primaryId) {
      this.primaryBundleId = primaryId;
      return this;
    }

    public Builder setFallbackBundleId(String fallbackId) {
      this.fallbackBundleId = fallbackId;
      return this;
    }

    public Builder setAppIcon(String appIcon) {
      this.appIcon = appIcon;
      return this;
    }

    public Builder setLaunchImage(String launchImage) {
      this.launchImage = launchImage;
      return this;
    }

    public Builder setLaunchStoryboard(Artifact launchStoryboard) {
      this.launchStoryboard = launchStoryboard;
      return this;
    }

    public Builder setProvisioningProfile(Artifact provisioningProfile) {
      this.provisioningProfile = provisioningProfile;
      return this;
    }

    public Builder setProvisioningProfileAttributeName(String provisioningProfileAttributeName) {
      this.provisioningProfileAttributeName = provisioningProfileAttributeName;
      return this;
    }

    public Builder addInfoplistInput(Artifact infoPlist) {
      this.infoplistInputs.add(infoPlist);
      return this;
    }

    public Builder addInfoplistInputs(Iterable<Artifact> infoplists) {
      this.infoplistInputs.addAll(infoplists);
      return this;
    }

    public Builder setInfoPlistsFromRule(Iterable<Artifact> infoPlistsFromRule) {
      this.infoPlistsFromRule = infoPlistsFromRule;
      return this;
    }

    public Builder setIntermediateArtifacts(IntermediateArtifacts intermediateArtifacts) {
      this.intermediateArtifacts = intermediateArtifacts;
      return this;
    }

    public Builder setTargetDeviceFamilies(ImmutableSet<TargetDeviceFamily> families) {
      this.families = families;
      return this;
    }

    public Builder setArtifactPrefix(String artifactPrefix) {
      this.artifactPrefix = artifactPrefix;
      return this;
    }

    public Builder setEntitlements(Artifact entitlements) {
      this.entitlements = entitlements;
      return this;
    }

    public ReleaseBundling build() {
      Preconditions.checkNotNull(intermediateArtifacts, "intermediateArtifacts");
      Preconditions.checkNotNull(families, FAMILIES_ATTR);
      return new ReleaseBundling(
          ipaArtifact,
          bundleId,
          primaryBundleId,
          fallbackBundleId,
          appIcon,
          launchImage,
          launchStoryboard,
          provisioningProfile,
          provisioningProfileAttributeName,
          infoplistInputs.build(),
          infoPlistsFromRule,
          families,
          intermediateArtifacts,
          artifactPrefix,
          entitlements,
          extraEntitlements);
    }
  }

  /**
   * Returns a {@link ReleaseBundling} object constructed using the information available in given
   * context.
   */
  public static ReleaseBundling releaseBundling(RuleContext ruleContext)
      throws InterruptedException {
    Preconditions.checkState(!Strings.isNullOrEmpty(
        ruleContext.attributes().get(BUNDLE_ID_ATTR, Type.STRING)),
        "requires a bundle_id value");
    String primaryBundleId = null;
    String fallbackBundleId = null;
    Artifact provisioningProfile;

    if (ruleContext.attributes().isAttributeValueExplicitlySpecified(BUNDLE_ID_ATTR)) {
      primaryBundleId = ruleContext.attributes().get(BUNDLE_ID_ATTR, Type.STRING);
    } else {
      fallbackBundleId = ruleContext.attributes().get(BUNDLE_ID_ATTR, Type.STRING);
    }

    Artifact explicitProvisioningProfile =
        ruleContext.getPrerequisiteArtifact(PROVISIONING_PROFILE_ATTR, Mode.TARGET);
    if (explicitProvisioningProfile != null) {
      provisioningProfile = explicitProvisioningProfile;
    } else {
      provisioningProfile = ruleContext.getPrerequisiteArtifact(DEFAULT_PROVISIONING_PROFILE_ATTR,
          Mode.TARGET);
    }

    ImmutableSet<TargetDeviceFamily> families = null;
    List<String> rawFamilies = ruleContext.attributes().get(FAMILIES_ATTR, Type.STRING_LIST);
    try {
      families = ImmutableSet.copyOf(TargetDeviceFamily.fromNamesInRule(rawFamilies));
    } catch (InvalidFamilyNameException | RepeatedFamilyNameException e) {
      families = ImmutableSet.of();
    }

    if (families.isEmpty()) {
      ruleContext.attributeError(FAMILIES_ATTR, INVALID_FAMILIES_ERROR);
    }

    return new ReleaseBundling.Builder()
        .setIpaArtifact(ruleContext.getImplicitOutputArtifact(ReleaseBundlingSupport.IPA))
        .setBundleId(ruleContext.attributes().get(BUNDLE_ID_ATTR, Type.STRING))
        .setPrimaryBundleId(primaryBundleId)
        .setFallbackBundleId(fallbackBundleId)
        .setAppIcon(Strings.emptyToNull(ruleContext.attributes().get(APP_ICON_ATTR, Type.STRING)))
        .setLaunchImage(Strings.emptyToNull(
            ruleContext.attributes().get(LAUNCH_IMAGE_ATTR, Type.STRING)))
        .setLaunchStoryboard(
            ruleContext.getPrerequisiteArtifact(LAUNCH_STORYBOARD_ATTR, Mode.TARGET))
        .setProvisioningProfile(provisioningProfile)
        .setProvisioningProfileAttributeName(PROVISIONING_PROFILE_ATTR)
        .setTargetDeviceFamilies(families)
        .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext))
        .setEntitlements(ruleContext.getPrerequisiteArtifact("entitlements", Mode.TARGET))
        .build();
  }

  @VisibleForTesting
  static final String INVALID_FAMILIES_ERROR =
      "Expected one or two strings from the list 'iphone', 'ipad'";
  private final Artifact ipaArtifact;
  private final String bundleId;
  private final String fallbackBundleId;
  private final String primaryBundleId;
  private final String appIcon;
  private final String launchImage;
  private final Artifact launchStoryboard;
  private final Artifact provisioningProfile;
  private final String provisioningProfileAttributeName;
  private final NestedSet<Artifact> infoplistInputs;
  private final ImmutableSet<TargetDeviceFamily> families;
  private final IntermediateArtifacts intermediateArtifacts;
  private final Iterable<Artifact> infoPlistsFromRule;
  private final String artifactPrefix;
  private final Artifact entitlements;

  private ReleaseBundling(
      Artifact ipaArtifact,
      String bundleId,
      String primaryBundleId,
      String fallbackBundleId,
      String appIcon,
      String launchImage,
      Artifact launchStoryboard,
      Artifact provisioningProfile,
      String provisioningProfileAttributeName,
      NestedSet<Artifact> infoplistInputs,
      Iterable<Artifact> infoPlistsFromRule,
      ImmutableSet<TargetDeviceFamily> families,
      IntermediateArtifacts intermediateArtifacts,
      String artifactPrefix,
      Artifact entitlements,
      Artifact extraEntitlements) {
    this.ipaArtifact = Preconditions.checkNotNull(ipaArtifact);
    this.bundleId = bundleId;
    this.primaryBundleId = primaryBundleId;
    this.fallbackBundleId = fallbackBundleId;
    this.appIcon = appIcon;
    this.launchImage = launchImage;
    this.launchStoryboard = launchStoryboard;
    this.provisioningProfile = provisioningProfile;
    this.provisioningProfileAttributeName =
        Preconditions.checkNotNull(provisioningProfileAttributeName);
    this.infoplistInputs = Preconditions.checkNotNull(infoplistInputs);
    this.infoPlistsFromRule = infoPlistsFromRule;
    this.families = Preconditions.checkNotNull(families);
    this.intermediateArtifacts = Preconditions.checkNotNull(intermediateArtifacts);
    this.artifactPrefix = artifactPrefix;
    this.entitlements = entitlements;
  }

  /**
   * Returns the {@link Artifact} containing the final ipa bundle.
   */
  public Artifact getIpaArtifact() {
    return ipaArtifact;
  }

  /**
   * Returns the identifier of this bundle.
   */
  public String getBundleId() {
    return bundleId;
  }

  /**
   * Returns primary bundle ID to use, can be null.
   */
  public String getPrimaryBundleId() {
    return primaryBundleId;
  }

  /**
   * Returns fallback bundle ID to use when primary isn't set.
   */
  public String getFallbackBundleId() {
    return fallbackBundleId;
  }

  /**
   * Returns the app icon name for this bundle, can be null.
   */
  public String getAppIcon() {
    return appIcon;
  }

  /**
   * Returns the launch image name for this bundle, can be null.
   */
  public String getLaunchImage() {
    return launchImage;
  }

  /**
   * Returns an {@link Artifact} containing launch storyboard for this bundle, can be null.
   */
  public Artifact getLaunchStoryboard() {
    return launchStoryboard;
  }

  /**
   * Returns an {@link Artifact} containing provisioning profile used to sign this bundle,
   * can be null.
   */
  public Artifact getProvisioningProfile() {
    return provisioningProfile;
  }

  /**
   * Returns the list of plists to be merged to final bundle.
   */
  public NestedSet<Artifact> getInfoplistInputs() {
    return infoplistInputs;
  }

  /**
   * Returns the list of {@link TargetDeviceFamily} values this bundle is targeting.
   * If empty, the default values specified by {@link FAMILIES_ATTR} will be used.
   */
  public ImmutableSet<TargetDeviceFamily> getTargetDeviceFamilies() {
    return families;
  }

  /**
   * Returns {@link IntermediateArtifacts} used to create this bundle.
   */
  public IntermediateArtifacts getIntermediateArtifacts() {
    return intermediateArtifacts;
  }

  /**
   * Returns the name of the attribute which is used to specifiy the provisioning profile.
   */
  public String getProvisioningProfileAttrName() {
    return provisioningProfileAttributeName;
  }

  /**
   * Adds any info plists specified in the given rule's {@code infoplists} attribute as inputs to
   * this bundle's {@code Info.plist} (which is merged from any such added plists plus some
   * additional information).
   */
  public Iterable<Artifact> getInfoPlistsFromRule() {
    return infoPlistsFromRule;
  }

  /**
   * Returns the prefix to be added to all generated artifact names, can be null. This is useful
   * to disambiguate artifacts for multiple bundles created with different names withing same rule. 
   */
  public String getArtifactPrefix() {
    return artifactPrefix;
  }

  /**
   * Returns an {@link Artifact} containing the entitlements used to sign this bundle for
   * non-simulator builds; can be null.
   */
  public Artifact getEntitlements() {
    return entitlements;
  }
}
