// 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 static com.google.devtools.build.lib.rules.objc.ObjcProvider.ASSET_CATALOG;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.BUNDLE_FILE;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.DYNAMIC_FRAMEWORK_FILE;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.Flag.USES_SWIFT;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.IMPORTED_LIBRARY;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.LIBRARY;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.MERGE_ZIP;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.MULTI_ARCH_LINKED_BINARIES;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.NESTED_BUNDLE;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.ROOT_MERGE_ZIP;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.STORYBOARD;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.STRINGS;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.XCDATAMODEL;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.XIB;
import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.BundlingRule.FAMILIES_ATTR;
import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.BundlingRule.INFOPLIST_ATTR;

import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
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.apple.AppleConfiguration;
import com.google.devtools.build.lib.rules.apple.DottedVersion;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;

/**
 * Contains information regarding the creation of an iOS bundle.
 */
@Immutable
final class Bundling {

  /**
   * Names of top-level directories in dynamic frameworks (i.e. directly under the
   * {@code *.framework} directory) that should not be copied into the final bundle.
   */
  private static final ImmutableSet<String> STRIP_FRAMEWORK_DIRS =
      ImmutableSet.of("Headers", "PrivateHeaders", "Modules");

  static final class Builder {
    private String name;
    private String bundleDirFormat;
    private ImmutableList.Builder<BundleableFile> bundleFilesBuilder = ImmutableList.builder();
    private ObjcProvider objcProvider;
    private NestedSetBuilder<Artifact> infoplistInputs = NestedSetBuilder.stableOrder();
    private Artifact automaticEntriesInfoplistInput;
    private IntermediateArtifacts intermediateArtifacts;
    private String primaryBundleId;
    private String fallbackBundleId;
    private String architecture;
    private DottedVersion minimumOsVersion;
    private ImmutableSet<TargetDeviceFamily> families;
    private String artifactPrefix;
    @Nullable private String executableName;

    public Builder setName(String name) {
      this.name = name;
      return this;
    }

    /** Sets the name of the bundle's executable. */
    public Builder setExecutableName(String executableName) {
      this.executableName = executableName;
      return this;
    }

    /**
     * Sets the CPU architecture this bundling was constructed for. Legal value are any that may be
     * set on {@link AppleConfiguration#getIosCpu()}.
     */
    public Builder setArchitecture(String architecture) {
      this.architecture = architecture;
      return this;
    }

    public Builder setBundleDirFormat(String bundleDirFormat) {
      this.bundleDirFormat = bundleDirFormat;
      return this;
    }

    public Builder addExtraBundleFiles(ImmutableList<BundleableFile> extraBundleFiles) {
      this.bundleFilesBuilder.addAll(extraBundleFiles);
      return this;
    }

    public Builder setObjcProvider(ObjcProvider objcProvider) {
      this.objcProvider = objcProvider;
      return this;
    }

    /**
     * Adds an artifact representing an {@code Info.plist} as an input to this bundle's
     * {@code Info.plist} (which is merged from any such added plists plus the generated
     * automatic entries plist).
     */
    public Builder addInfoplistInput(Artifact infoplist) {
      this.infoplistInputs.add(infoplist);
      return this;
    }

    /**
     * Adds the given list of artifacts representing {@code Info.plist}s that are to be merged into
     * this bundle's {@code Info.plist}.
     */
    public Builder addInfoplistInputs(Iterable<Artifact> infoplists) {
      this.infoplistInputs.addAll(infoplists);
      return this;
    }

    /**
     * Adds an artifact representing an {@code Info.plist} that contains automatic entries
     * generated by xcode.
     */
    public Builder setAutomaticEntriesInfoplistInput(Artifact automaticEntriesInfoplist) {
      this.automaticEntriesInfoplistInput = automaticEntriesInfoplist;
      return this;
    }

    /**
     * Adds any info plists specified in the given rule's {@code infoplist}  or {@code infoplists}
     * attribute as well as from its {@code options} as inputs to this bundle's {@code Info.plist}
     * (which is merged from any such added plists plus some additional information).
     */
    public Builder addInfoplistInputFromRule(RuleContext ruleContext) {
      Artifact infoplist =
          ruleContext.getPrerequisiteArtifact(INFOPLIST_ATTR, Mode.TARGET);
      if (infoplist != null) {
        infoplistInputs.add(infoplist);
      }

      Iterable<Artifact> infoplists =
          ruleContext.getPrerequisiteArtifacts("infoplists", Mode.TARGET).list();
      if (infoplists != null) {
        infoplistInputs.addAll(infoplists);
      }

      return this;
    }

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

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

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

    /**
     * Sets the minimum OS version for this bundle which will be used when constructing the bundle's
     * plist.
     */
    public Builder setMinimumOsVersion(DottedVersion minimumOsVersion) {
      this.minimumOsVersion = minimumOsVersion;
      return this;
    }

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

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

    private static NestedSet<Artifact> nestedBundleContentArtifacts(Iterable<Bundling> bundles) {
      NestedSetBuilder<Artifact> artifacts = NestedSetBuilder.stableOrder();
      for (Bundling bundle : bundles) {
        artifacts.addTransitive(bundle.getBundleContentArtifacts());
      }
      return artifacts.build();
    }

    private NestedSet<Artifact> mergeZips(Optional<Artifact> actoolzipOutput) {
      NestedSetBuilder<Artifact> mergeZipBuilder =
          NestedSetBuilder.<Artifact>stableOrder()
              .addAll(actoolzipOutput.asSet())
              .addAll(
                  Xcdatamodel.outputZips(
                      Xcdatamodels.xcdatamodels(
                          intermediateArtifacts, objcProvider.get(XCDATAMODEL))))
              .addTransitive(objcProvider.get(MERGE_ZIP));
      for (Artifact xibFile : objcProvider.get(XIB)) {
        mergeZipBuilder.add(intermediateArtifacts.compiledXibFileZip(xibFile));
      }
      for (Artifact storyboard : objcProvider.get(STORYBOARD)) {
        mergeZipBuilder.add(intermediateArtifacts.compiledStoryboardZip(storyboard));
      }

      if (objcProvider.is(USES_SWIFT)) {
        mergeZipBuilder.add(intermediateArtifacts.swiftFrameworksFileZip());
      }

      return mergeZipBuilder.build();
    }

    private NestedSet<Artifact> rootMergeZips() {
      NestedSetBuilder<Artifact> rootMergeZipsBuilder =
          NestedSetBuilder.<Artifact>stableOrder().addTransitive(objcProvider.get(ROOT_MERGE_ZIP));

      if (objcProvider.is(USES_SWIFT)) {
        rootMergeZipsBuilder.add(intermediateArtifacts.swiftSupportZip());
      }

      return rootMergeZipsBuilder.build();
    }

    private NestedSet<Artifact> bundleInfoplistInputs() {
      if (objcProvider.hasAssetCatalogs()) {
        infoplistInputs.add(intermediateArtifacts.actoolPartialInfoplist());
      }
      return infoplistInputs.build();
    }

    private Optional<Artifact> bundleInfoplist(NestedSet<Artifact> bundleInfoplistInputs) {
      if (bundleInfoplistInputs.isEmpty()) {
        return Optional.absent();
      }
      if (needsToMerge(bundleInfoplistInputs, primaryBundleId, fallbackBundleId)) {
        return Optional.of(intermediateArtifacts.mergedInfoplist());
      }
      return Optional.of(Iterables.getOnlyElement(bundleInfoplistInputs));
    }

    private Optional<Artifact> combinedArchitectureBinary() {
      if (!Iterables.isEmpty(objcProvider.get(MULTI_ARCH_LINKED_BINARIES))) {
        return Optional.of(Iterables.getOnlyElement(objcProvider.get(MULTI_ARCH_LINKED_BINARIES)));
      } else if (!Iterables.isEmpty(objcProvider.get(LIBRARY))
          || !Iterables.isEmpty(objcProvider.get(IMPORTED_LIBRARY))) {
        return Optional.of(intermediateArtifacts.combinedArchitectureBinary());
      }
      return Optional.absent();
    }

    private Optional<Artifact> actoolzipOutput() {
      Optional<Artifact> actoolzipOutput = Optional.absent();
      if (!Iterables.isEmpty(objcProvider.get(ASSET_CATALOG))) {
        actoolzipOutput = Optional.of(intermediateArtifacts.actoolzipOutput());
      }
      return actoolzipOutput;
    }

    private NestedSet<BundleableFile> binaryStringsFiles() {
      NestedSetBuilder<BundleableFile> binaryStringsBuilder = NestedSetBuilder.stableOrder();
      for (Artifact stringsFile : objcProvider.get(STRINGS)) {
        BundleableFile bundleFile =
            new BundleableFile(
                intermediateArtifacts.convertedStringsFile(stringsFile),
                BundleableFile.flatBundlePath(stringsFile.getExecPath()));
        binaryStringsBuilder.add(bundleFile);
      }
      return binaryStringsBuilder.build();
    }

    private NestedSet<BundleableFile> dynamicFrameworkFiles() {
      NestedSetBuilder<BundleableFile> frameworkFilesBuilder = NestedSetBuilder.stableOrder();
      for (Artifact frameworkFile : objcProvider.get(DYNAMIC_FRAMEWORK_FILE)) {
        PathFragment frameworkDir =
            ObjcCommon.nearestContainerMatching(ObjcCommon.FRAMEWORK_CONTAINER_TYPE, frameworkFile)
                .get();
        String frameworkName = frameworkDir.getBaseName();
        PathFragment inFrameworkPath = frameworkFile.getExecPath().relativeTo(frameworkDir);
        if (inFrameworkPath.getFirstSegment(STRIP_FRAMEWORK_DIRS) == 0) {
          continue;
        }
        // If this is a top-level file in the framework set the executable bit (to make sure we set
        // the bit on the actual dylib binary - other files may also get it but we have no way to
        // distinguish them).
        int permissions =
            inFrameworkPath.segmentCount() == 1
                ? BundleableFile.EXECUTABLE_EXTERNAL_FILE_ATTRIBUTE
                : BundleableFile.DEFAULT_EXTERNAL_FILE_ATTRIBUTE;
        BundleableFile bundleFile =
            new BundleableFile(
                frameworkFile,
                "Frameworks/" + frameworkName + "/" + inFrameworkPath.getPathString(),
                permissions);
        frameworkFilesBuilder.add(bundleFile);
      }
      return frameworkFilesBuilder.build();
    }

    /**
     * Filters files that would map to the same location in the bundle, adding only one copy to the
     * set of files returned.
     *
     * <p>Files can have the same bundle path for various illegal reasons and errors are raised for
     * that separately (see {@link BundleSupport#validateResources}). There are situations though
     * where the same file exists multiple times (for example in multi-architecture builds) and
     * would conflict when creating the bundle. In all these cases it shouldn't matter which one is
     * included and this class will select the first one.
     */
    ImmutableList<BundleableFile> deduplicateByBundlePaths(
        ImmutableList<BundleableFile> bundleFiles) {
      ImmutableList.Builder<BundleableFile> deduplicated = ImmutableList.builder();
      Set<String> bundlePaths = new HashSet<>();
      for (BundleableFile bundleFile : bundleFiles) {
        if (bundlePaths.add(bundleFile.getBundlePath())) {
          deduplicated.add(bundleFile);
        }
      }
      return deduplicated.build();
    }

    public Bundling build() {
      Preconditions.checkNotNull(intermediateArtifacts, "intermediateArtifacts");
      Preconditions.checkNotNull(families, FAMILIES_ATTR);
      NestedSet<Artifact> bundleInfoplistInputs = bundleInfoplistInputs();
      Optional<Artifact> bundleInfoplist = bundleInfoplist(bundleInfoplistInputs);
      Optional<Artifact> actoolzipOutput = actoolzipOutput();
      Optional<Artifact> combinedArchitectureBinary = combinedArchitectureBinary();
      NestedSet<BundleableFile> binaryStringsFiles = binaryStringsFiles();
      NestedSet<BundleableFile> dynamicFrameworks = dynamicFrameworkFiles();
      NestedSet<Artifact> mergeZips = mergeZips(actoolzipOutput);
      NestedSet<Artifact> rootMergeZips = rootMergeZips();

      bundleFilesBuilder
          .addAll(binaryStringsFiles)
          .addAll(dynamicFrameworks)
          .addAll(objcProvider.get(BUNDLE_FILE));
      ImmutableList<BundleableFile> bundleFiles =
          deduplicateByBundlePaths(bundleFilesBuilder.build());

      NestedSetBuilder<Artifact> bundleContentArtifactsBuilder =
          NestedSetBuilder.<Artifact>stableOrder()
              .addTransitive(nestedBundleContentArtifacts(objcProvider.get(NESTED_BUNDLE)))
              .addAll(combinedArchitectureBinary.asSet())
              .addAll(bundleInfoplist.asSet())
              .addTransitive(mergeZips)
              .addTransitive(rootMergeZips)
              .addAll(BundleableFile.toArtifacts(bundleFiles));

      return new Bundling(
          name,
          executableName,
          bundleDirFormat,
          combinedArchitectureBinary,
          bundleFiles,
          bundleInfoplist,
          actoolzipOutput,
          bundleContentArtifactsBuilder.build(),
          mergeZips,
          rootMergeZips,
          primaryBundleId,
          fallbackBundleId,
          architecture,
          minimumOsVersion,
          bundleInfoplistInputs,
          automaticEntriesInfoplistInput,
          objcProvider.get(NESTED_BUNDLE),
          families,
          intermediateArtifacts,
          artifactPrefix);
    }
  }

  private static boolean needsToMerge(
      NestedSet<Artifact> bundleInfoplistInputs, String primaryBundleId, String fallbackBundleId) {
    return primaryBundleId != null || fallbackBundleId != null
        || Iterables.size(bundleInfoplistInputs) > 1;
  }

  private final String name;
  @Nullable private final String executableName;
  private final String architecture;
  private final String bundleDirFormat;
  private final Optional<Artifact> combinedArchitectureBinary;
  private final ImmutableList<BundleableFile> bundleFiles;
  private final Optional<Artifact> bundleInfoplist;
  private final Optional<Artifact> actoolzipOutput;
  private final NestedSet<Artifact> bundleContentArtifacts;
  private final NestedSet<Artifact> mergeZips;
  private final NestedSet<Artifact> rootMergeZips;
  private final String primaryBundleId;
  private final String fallbackBundleId;
  private final DottedVersion minimumOsVersion;
  private final NestedSet<Artifact> infoplistInputs;
  private final NestedSet<Bundling> nestedBundlings;
  private Artifact automaticEntriesInfoplistInput;
  private final ImmutableSet<TargetDeviceFamily> families;
  private final IntermediateArtifacts intermediateArtifacts;
  private final String artifactPrefix;

  private Bundling(
      String name,
      String executableName,
      String bundleDirFormat,
      Optional<Artifact> combinedArchitectureBinary,
      ImmutableList<BundleableFile> bundleFiles,
      Optional<Artifact> bundleInfoplist,
      Optional<Artifact> actoolzipOutput,
      NestedSet<Artifact> bundleContentArtifacts,
      NestedSet<Artifact> mergeZips,
      NestedSet<Artifact> rootMergeZips,
      String primaryBundleId,
      String fallbackBundleId,
      String architecture,
      DottedVersion minimumOsVersion,
      NestedSet<Artifact> infoplistInputs,
      Artifact automaticEntriesInfoplistInput,
      NestedSet<Bundling> nestedBundlings,
      ImmutableSet<TargetDeviceFamily> families,
      IntermediateArtifacts intermediateArtifacts,
      String artifactPrefix) {
    this.nestedBundlings = Preconditions.checkNotNull(nestedBundlings);
    this.name = Preconditions.checkNotNull(name);
    this.executableName = executableName;
    this.bundleDirFormat = Preconditions.checkNotNull(bundleDirFormat);
    this.combinedArchitectureBinary = Preconditions.checkNotNull(combinedArchitectureBinary);
    this.bundleFiles = Preconditions.checkNotNull(bundleFiles);
    this.bundleInfoplist = Preconditions.checkNotNull(bundleInfoplist);
    this.actoolzipOutput = Preconditions.checkNotNull(actoolzipOutput);
    this.bundleContentArtifacts = Preconditions.checkNotNull(bundleContentArtifacts);
    this.mergeZips = Preconditions.checkNotNull(mergeZips);
    this.rootMergeZips = Preconditions.checkNotNull(rootMergeZips);
    this.fallbackBundleId = fallbackBundleId;
    this.primaryBundleId = primaryBundleId;
    this.architecture = Preconditions.checkNotNull(architecture);
    this.minimumOsVersion = Preconditions.checkNotNull(minimumOsVersion);
    this.infoplistInputs = Preconditions.checkNotNull(infoplistInputs);
    this.automaticEntriesInfoplistInput = automaticEntriesInfoplistInput;
    this.families = Preconditions.checkNotNull(families);
    this.intermediateArtifacts = intermediateArtifacts;
    this.artifactPrefix = artifactPrefix;
  }

  /**
   * The bundle directory. For apps, this would be {@code "Payload/TARGET_NAME.app"}, which is where
   * in the bundle zip archive every file is found, including the linked binary, nested bundles, and
   * everything returned by {@link #getBundleFiles()}.
   */
  public String getBundleDir() {
    return String.format(bundleDirFormat, name);
  }

  /**
   * The name of the bundle, from which the bundle root and the path of the linked binary in the
   * bundle archive are derived.
   */
  public String getName() {
    return name;
  }
  
  /** The name of the bundle's executable, or null if the bundle has no executable. */
  @Nullable public String getExecutableName() {
    return executableName;
  }

  /**
   * An {@link Optional} with the linked binary artifact, or {@link Optional#absent()} if it is
   * empty and should not be included in the bundle.
   */
  public Optional<Artifact> getCombinedArchitectureBinary() {
    return combinedArchitectureBinary;
  }

  /**
   * Bundle files to include in the bundle. These files are placed under the bundle root (possibly
   * nested, of course, depending on the bundle path of the files).
   */
  public ImmutableList<BundleableFile> getBundleFiles() {
    return bundleFiles;
  }

  /**
   * Returns any bundles nested in this one.
   */
  public NestedSet<Bundling> getNestedBundlings() {
    return nestedBundlings;
  }

  /**
   * Returns an artifact representing this bundle's {@code Info.plist} or {@link Optional#absent()}
   * if this bundle has no info plist inputs.
   */
  public Optional<Artifact> getBundleInfoplist() {
    return bundleInfoplist;
  }

  /**
   * Returns all info plists that need to be merged into this bundle's {@link #getBundleInfoplist()
   * info plist}, other than that plist that contains blaze-generated automatic entires.
   */
  public NestedSet<Artifact> getBundleInfoplistInputs() {
    return infoplistInputs;
  }

  /**
   * Returns an artifact representing a plist containing automatic entries generated by bazel.
   */
  public Artifact getAutomaticInfoPlist() {
    return automaticEntriesInfoplistInput;
  }

  /**
   * Returns all artifacts that are required as input to the merging of the final plist.
   */
  public NestedSet<Artifact> getMergingContentArtifacts() {
    NestedSetBuilder<Artifact> result = NestedSetBuilder.stableOrder();
    result.addTransitive(infoplistInputs);
    if (automaticEntriesInfoplistInput != null) {
      result.add(automaticEntriesInfoplistInput);
    }
    return result.build();
  }

  /**
   * Returns {@code true} if this bundle requires merging of its {@link #getBundleInfoplist() info
   * plist}.
   */
  public boolean needsToMergeInfoplist() {
    return needsToMerge(infoplistInputs, primaryBundleId, fallbackBundleId);
  }

  /**
   * The location of the actoolzip output for this bundle. This is non-absent only included in the
   * bundle if there is at least one asset catalog artifact supplied by
   * {@link ObjcProvider#ASSET_CATALOG}.
   */
  public Optional<Artifact> getActoolzipOutput() {
    return actoolzipOutput;
  }

  /**
   * Returns all zip files whose contents should be merged into this bundle under the main bundle
   * directory. For instance, if a merge zip contains files a/b and c/d, then the resulting bundling
   * would have additional files at:
   * <ul>
   *   <li>{bundleDir}/a/b
   *   <li>{bundleDir}/c/d
   * </ul>
   */
  public NestedSet<Artifact> getMergeZips() {
    return mergeZips;
  }

  /**
   * Returns all zip files whose contents should be merged into final ipa and outside the
   * main bundle. For instance, if a merge zip contains files dir1/file1, then the resulting
   * bundling would have additional files at:
   * <ul>
   *   <li>dir1/file1
   *   <li>{bundleDir}/other_files
   * </ul>
   */
  public NestedSet<Artifact> getRootMergeZips() {
    return rootMergeZips;
  }

  /**
   * Returns the variable substitutions that should be used when merging the plist info file of
   * this bundle.
   */
  public Map<String, String> variableSubstitutions() {
    return ImmutableMap.of(
        "EXECUTABLE_NAME", Strings.nullToEmpty(executableName),
        "BUNDLE_NAME", PathFragment.create(getBundleDir()).getBaseName(),
        "PRODUCT_NAME", name);
  }

  /**
   * Returns the artifacts that are required to generate this bundle.
   */
  public NestedSet<Artifact> getBundleContentArtifacts() {
    return bundleContentArtifacts;
  }

  /**
   * 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 iOS CPU architecture this bundle was constructed for.
   */
  public String getArchitecture() {
    return architecture;
  }

  /**
   * Returns the minimum iOS version this bundle's plist and resources should be generated for
   * (does <b>not</b> affect the minimum OS version its binary is compiled with).
   */
  public DottedVersion getMinimumOsVersion() {
    return minimumOsVersion;
  }

  /**
   * 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} required to create this bundle.
   */
  public IntermediateArtifacts getIntermediateArtifacts() {
    return intermediateArtifacts;
  }

  /**
   * 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 within same rule.
   */
  public String getArtifactPrefix() {
    return artifactPrefix;
  }
}
