// 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.io.ByteSource;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
import com.google.devtools.build.lib.rules.apple.Platform.PlatformType;
import com.google.devtools.build.lib.util.Preconditions;
import com.google.devtools.build.xcode.bundlemerge.proto.BundleMergeProtos;
import com.google.devtools.build.xcode.bundlemerge.proto.BundleMergeProtos.Control;
import com.google.devtools.build.xcode.bundlemerge.proto.BundleMergeProtos.MergeZip;

import java.io.InputStream;

/**
 * A byte source that can be used to generate a control file for the tool bundlemerge . 
 * Note that this generates the control proto and bytes on-the-fly rather than eagerly. 
 * This is to prevent a copy of the bundle files and .xcdatamodels from being stored for 
 * each {@code objc_binary} (or any bundle) being built.
 */
// TODO(bazel-team): Move the logic in this class to Bundling (as a .toControl method).
final class BundleMergeControlBytes extends ByteSource {
  private final Bundling rootBundling;
  private final Artifact mergedIpa;
  private final AppleConfiguration appleConfiguration;

  public BundleMergeControlBytes(
      Bundling rootBundling, Artifact mergedIpa, AppleConfiguration appleConfiguration) {
    this.rootBundling = Preconditions.checkNotNull(rootBundling);
    this.mergedIpa = Preconditions.checkNotNull(mergedIpa);
    this.appleConfiguration = Preconditions.checkNotNull(appleConfiguration);
  }

  @Override
  public InputStream openStream() {
    return control("", rootBundling).toByteString().newInput();
  }

  private Control control(String mergeZipPrefix, Bundling bundling) {
    mergeZipPrefix += bundling.getBundleDir() + "/";

    BundleMergeProtos.Control.Builder control =
        BundleMergeProtos.Control.newBuilder()
            .addAllBundleFile(BundleableFile.toBundleFiles(bundling.getBundleFiles()))
            // TODO(bazel-team): Add rule attribute for specifying targeted device family
            .setMinimumOsVersion(bundling.getMinimumOsVersion().toString())
            .setSdkVersion(appleConfiguration.getIosSdkVersion().toString())
            .setPlatform(appleConfiguration.getMultiArchPlatform(PlatformType.IOS).name())
            .setBundleRoot(bundling.getBundleDir());

    if (bundling.getBundleInfoplist().isPresent()) {
      control.setBundleInfoPlistFile((bundling.getBundleInfoplist().get().getExecPathString()));
    }

    for (Artifact mergeZip : bundling.getMergeZips()) {
      control.addMergeZip(MergeZip.newBuilder()
          .setEntryNamePrefix(mergeZipPrefix)
          .setSourcePath(mergeZip.getExecPathString())
          .build());
    }

    for (Artifact rootMergeZip : bundling.getRootMergeZips()) {
      control.addMergeZip(MergeZip.newBuilder()
          .setEntryNamePrefix("")
          .setSourcePath(rootMergeZip.getExecPathString())
          .build());
    }

    control.setOutFile(mergedIpa.getExecPathString());

    for (Artifact linkedBinary : bundling.getCombinedArchitectureBinary().asSet()) {
      control.addBundleFile(
          BundleMergeProtos.BundleFile.newBuilder()
              .setSourceFile(linkedBinary.getExecPathString())
              .setBundlePath(bundling.getName())
              .setExternalFileAttribute(BundleableFile.EXECUTABLE_EXTERNAL_FILE_ATTRIBUTE)
              .build());
    }

    for (Bundling nestedBundling : bundling.getNestedBundlings()) {
      if (nestedBundling.getArchitecture().equals(bundling.getArchitecture())) {
        control.addNestedBundle(control(mergeZipPrefix, nestedBundling));
      }
    }
    
    if (bundling.getPrimaryBundleId() != null) {
      control.setPrimaryBundleIdentifier(bundling.getPrimaryBundleId());
    }
    
    if (bundling.getFallbackBundleId() != null) {
      control.setFallbackBundleIdentifier(bundling.getFallbackBundleId());
    }
    
    return control.build();
  }
}
