/*
 * Copyright 2012-present Facebook, Inc.
 *
 * 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.facebook.buck.android;

import com.android.common.annotations.NonNull;
import com.android.common.utils.StdLogger;
import com.android.manifmerger.ICallback;
import com.android.manifmerger.IMergerLog;
import com.android.manifmerger.ManifestMerger;
import com.android.manifmerger.MergerLog;
import com.facebook.buck.step.ExecutionContext;
import com.facebook.buck.step.Step;
import com.facebook.buck.util.HumanReadableException;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

import java.io.File;
import java.util.List;

public class GenerateManifestStep implements Step {

  private static final int BASE_SDK_LEVEL = 1;

  private String skeletonManifestPath;
  private String outManifestPath;
  private ImmutableSet<String> libraryManifestPaths;

  public GenerateManifestStep(
      String skeletonManifestPath,
      String outManifestPath,
      ImmutableSet<String> libraryManifestPaths) {
    this.skeletonManifestPath = Preconditions.checkNotNull(skeletonManifestPath);
    this.outManifestPath = Preconditions.checkNotNull(outManifestPath);
    this.libraryManifestPaths = ImmutableSet.copyOf(libraryManifestPaths);
  }

  @Override
  public int execute(ExecutionContext context) {

    if (Strings.isNullOrEmpty(skeletonManifestPath)) {
      throw new HumanReadableException("Skeleton manifest filepath is missing");
    }

    if (Strings.isNullOrEmpty(outManifestPath)) {
      throw new HumanReadableException("Output Manifest filepath is missing");
    }

    if (libraryManifestPaths == null || libraryManifestPaths.isEmpty()) {
      warnUser(context, "No library manifests found. Aborting manifest merge step.");
      return 1;
    }

    List<File> libraryManifestFiles = Lists.newArrayList();

    for (String path : libraryManifestPaths) {
      libraryManifestFiles.add(new File(path));
    }

    File skeletonManifestFile = new File(skeletonManifestPath);

    ICallback callback = new ICallback() {
      @Override
      public int queryCodenameApiLevel(@NonNull String codename) {
        return BASE_SDK_LEVEL;
      }
    };

    IMergerLog log = MergerLog.wrapSdkLog(new StdLogger(StdLogger.Level.VERBOSE));

    ManifestMerger merger = new ManifestMerger(log, callback);
    if (!merger.process(
        new File(outManifestPath),
        skeletonManifestFile,
        Iterables.toArray(libraryManifestFiles, File.class))) {
      throw new HumanReadableException("Error generating manifest file");
    }

    return 0;
  }

  @Override
  public String getDescription(ExecutionContext context) {
    return String.format("generate-manifest %s", skeletonManifestPath);
  }

  @Override
  public String getShortName(ExecutionContext context) {
    return "generate-manifest";
  }

  private void warnUser(ExecutionContext context, String message) {
    context.getStdErr().println(context.getAnsi().asWarningText(message));
  }
}
