/*
 * 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.sdklib.build.ApkBuilder;
import com.facebook.buck.shell.ShellStep;
import com.facebook.buck.step.ExecutionContext;
import com.facebook.buck.util.MoreStrings;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;

import java.nio.file.Path;

/**
 * Runs the Android Asset Packaging Tool ({@code aapt}), which creates an {@code .apk} file.
 * Frequently, the {@code pathsToRawFilesDirs} excludes {@code classes.dex}, as {@code classes.dex}
 * will be added separately to the final APK via {@link ApkBuilder}.
 */
public class AaptStep extends ShellStep {

  // aapt, unless specified a pattern, ignores certain files and directories. We follow the same
  // logic as the default pattern found at http://goo.gl/OTTK88 and line 61.
  private static final String DEFAULT_IGNORE_ASSETS_PATTERN =
      "\\!.svn:\\!.git:\\!.ds_store:\\!*.scc:.*:<dir>_*:\\!CVS:\\!thumbs.db:\\!picasa.ini:\\!*~";

  // Ignore *.orig files generated by mercurial.
  public static final String IGNORE_ASSETS_PATTERN = DEFAULT_IGNORE_ASSETS_PATTERN + ":*.orig";

  /**
   * Determines whether the default AAPT ignore pattern in
   * {@link com.facebook.buck.android.AaptStep#DEFAULT_IGNORE_ASSETS_PATTERN}
   * would silently ignore a file.
   *
   * @param path The path of the file we are interested in.
   * @return Whether the file would be silently ignored.
   */
  public static boolean isSilentlyIgnored(Path path) {
    String fileName = path.getFileName().toString();
    return
        ".svn".equalsIgnoreCase(fileName) ||
        ".git".equalsIgnoreCase(fileName) ||
        ".ds_store".equalsIgnoreCase(fileName) ||
        MoreStrings.endsWithIgnoreCase(fileName, ".scc") ||
        "cvs".equalsIgnoreCase(fileName) ||
        "thumbs.db".equalsIgnoreCase(fileName) ||
        "picasa.ini".equalsIgnoreCase(fileName) ||
        fileName.endsWith("~");
  }

  private final Path androidManifest;
  private final ImmutableList<Path> resDirectories;
  private final Optional<Path> assetsDirectory;
  private final Path pathToOutputApkFile;
  private final Path pathToRDotTxtDir;
  private final Optional<Path> pathToGeneratedProguardConfig;

  private final boolean isCrunchPngFiles;

  public AaptStep(
      Path androidManifest,
      ImmutableList<Path> resDirectories,
      Optional<Path> assetsDirectory,
      Path pathToOutputApkFile,
      Path pathToRDotTxtDir,
      Optional<Path> pathToGeneratedProguardConfig,
      boolean isCrunchPngFiles) {
    this.androidManifest = androidManifest;
    this.resDirectories = resDirectories;
    this.assetsDirectory = assetsDirectory;
    this.pathToOutputApkFile = pathToOutputApkFile;
    this.pathToRDotTxtDir = pathToRDotTxtDir;
    this.pathToGeneratedProguardConfig = pathToGeneratedProguardConfig;
    this.isCrunchPngFiles = isCrunchPngFiles;
  }

  @Override
  protected ImmutableList<String> getShellCommandInternal(ExecutionContext context) {
    ImmutableList.Builder<String> builder = ImmutableList.builder();
    AndroidPlatformTarget androidPlatformTarget = context.getAndroidPlatformTarget();

    builder.add(androidPlatformTarget.getAaptExecutable().toString());
    builder.add("package");

    // verbose flag, if appropriate.
    if (context.getVerbosity().shouldUseVerbosityFlagIfAvailable()) {
      builder.add("-v");
    }

    // Force overwrite of existing files.
    builder.add("-f");

    if (pathToGeneratedProguardConfig.isPresent()) {
      builder.add("-G", pathToGeneratedProguardConfig.get().toString());
    }

    // --no-crunch, if appropriate.
    if (!isCrunchPngFiles) {
       builder.add("--no-crunch");
    }

    // Include all of the res/ directories.
    builder.add("--auto-add-overlay");
    for (Path res : resDirectories) {
      builder.add("-S", res.toString());
    }

    // Include the assets/ directory, if any.
    // According to the aapt documentation, it appears that it should be possible to specify the -A
    // flag multiple times; however, in practice, when it is specified multiple times, only one of
    // the folders is included in the final APK.
    if (assetsDirectory.isPresent()) {
      builder.add("-A", assetsDirectory.get().toString());
    }

    builder.add("--output-text-symbols").add(pathToRDotTxtDir.toString());
    builder.add("-J").add(pathToRDotTxtDir.toString());

    builder.add("-M").add(androidManifest.toString());
    builder.add("-I", androidPlatformTarget.getAndroidJar().toString());
    builder.add("-F", pathToOutputApkFile.toString());

    builder.add("--ignore-assets", IGNORE_ASSETS_PATTERN);

    return builder.build();
  }

  @Override
  public String getShortName() {
    return String.format("aapt_package");
  }

}
