/*
 * 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.util;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Represents a platform to target for Android. Eventually, it should be possible to construct an
 * arbitrary platform target, but currently, we only recognize a fixed set of targets.
 */
public class AndroidPlatformTarget {

  static final String DEFAULT_ANDROID_PLATFORM_TARGET = "Google Inc.:Google APIs:16";

  private final String name;
  private final File androidJar;
  private final List<File> bootclasspathEntries;
  private final File aaptExecutable;
  private final File adbExecutable;
  private final File aidlExecutable;
  private final File zipalignExecutable;
  private final File dxExecutable;
  private final File androidFrameworkIdlFile;
  private final File proguardJar;
  private final File proguardConfig;
  private final File optimizedProguardConfig;

  private AndroidPlatformTarget(
      String name,
      File androidJar,
      List<File> bootclasspathEntries,
      File aaptExecutable,
      File adbExecutable,
      File aidlExecutable,
      File zipalignExecutable,
      File dxExecutable,
      File androidFrameworkIdlFile,
      File proguardJar,
      File proguardConfig,
      File optimizedProguardConfig) {
    this.name = Preconditions.checkNotNull(name);
    this.androidJar = Preconditions.checkNotNull(androidJar);
    this.bootclasspathEntries = ImmutableList.copyOf(bootclasspathEntries);
    this.aaptExecutable = Preconditions.checkNotNull(aaptExecutable);
    this.adbExecutable = Preconditions.checkNotNull(adbExecutable);
    this.aidlExecutable = Preconditions.checkNotNull(aidlExecutable);
    this.zipalignExecutable = Preconditions.checkNotNull(zipalignExecutable);
    this.dxExecutable = Preconditions.checkNotNull(dxExecutable);
    this.androidFrameworkIdlFile = Preconditions.checkNotNull(androidFrameworkIdlFile);
    this.proguardJar = Preconditions.checkNotNull(proguardJar);
    this.proguardConfig = Preconditions.checkNotNull(proguardConfig);
    this.optimizedProguardConfig = Preconditions.checkNotNull(optimizedProguardConfig);
  }

  public String getName() {
    return name;
  }

  @Override
  public String toString() {
    return getName();
  }

  public File getAndroidJar() {
    return androidJar;
  }

  public List<File> getBootclasspathEntries() {
    return bootclasspathEntries;
  }

  public File getAaptExecutable() {
    return aaptExecutable;
  }

  public File getAdbExecutable() {
    return adbExecutable;
  }

  public File getAidlExecutable() {
    return aidlExecutable;
  }

  public File getZipalignExecutable() {
    return zipalignExecutable;
  }

  public File getDxExecutable() {
    return dxExecutable;
  }

  public File getAndroidFrameworkIdlFile() {
    return androidFrameworkIdlFile;
  }

  public File getProguardJar() {
    return proguardJar;
  }

  public File getProguardConfig() {
    return proguardConfig;
  }

  public File getOptimizedProguardConfig() {
    return optimizedProguardConfig;
  }

  /**
   * @param platformId for the platform, such as "Google Inc.:Google APIs:16"
   * @param androidSdkDir directory where the user's Android SDK is installed
   */
  public static Optional<AndroidPlatformTarget> getTargetForId(
      String platformId,
      File androidSdkDir) {
    Preconditions.checkNotNull(platformId);
    Preconditions.checkNotNull(androidSdkDir);

    Pattern platformPattern = Pattern.compile("Google Inc\\.:Google APIs:(\\d+)");
    Matcher platformMatcher = platformPattern.matcher(platformId);
    if (platformMatcher.matches()) {
      try {
        int apiLevel = Integer.parseInt(platformMatcher.group(1));
        return Optional.of(new AndroidWithGoogleApisFactory().newInstance(androidSdkDir, apiLevel));
      } catch (NumberFormatException e) {
        return Optional.absent();
      }
    } else {
      return Optional.absent();
    }
  }

  public static AndroidPlatformTarget getDefaultPlatformTarget(File androidSdkDir) {
    return getTargetForId(DEFAULT_ANDROID_PLATFORM_TARGET, androidSdkDir).get();
  }

  private static interface Factory {
    public AndroidPlatformTarget newInstance(File androidSdkDir, int apiLevel);
  }

  /**
   * Resolves all of the jarPaths against the androidSdkDir path.
   * @return a mutable list
   */
  private static LinkedList<File> resolvePaths(final File androidSdkDir, Set<String> jarPaths) {
    return Lists.newLinkedList(Iterables.transform(jarPaths, new Function<String, File>() {
      @Override
      public File apply(String jarPath) {
        File jar = new File(androidSdkDir, jarPath);
        if (!jar.isFile()) {
          throw new RuntimeException("File not found: " + jar.getAbsolutePath());
        }
        return jar;
      }
    }));
  }

  /**
   * Given the path to the Android SDK as well as the platform path within the Android SDK,
   * find all the files needed to create the {@link AndroidPlatformTarget}, assuming that the
   * organization of the Android SDK conforms to the ordinary directory structure.
   */
  @VisibleForTesting
  static AndroidPlatformTarget createFromDefaultDirectoryStructure(
      String name,
      File androidSdkDir,
      String platformDirectoryPath,
      Set<String> additionalJarPaths) {
    File platformDirectory = new File(androidSdkDir, platformDirectoryPath);
    File androidJar = new File(platformDirectory, "android.jar");
    LinkedList<File> bootclasspathEntries = resolvePaths(androidSdkDir, additionalJarPaths);

    // Make sure android.jar is at the front of the bootclasspath.
    bootclasspathEntries.addFirst(androidJar);

    File buildToolsDir = new File(androidSdkDir, "build-tools");

    // This is the relative path under the Android SDK directory to the directory that contains the
    // aapt, aidl, and dx executables.
    String buildToolsPath;

    if (buildToolsDir.isDirectory()) {
      // In older versions of the ADT that have been upgraded via the SDK manager, the build-tools
      // directory appears to contain subfolders of the form "17.0.0". However, newer versions of
      // the ADT that are downloaded directly from http://developer.android.com/ appear to have
      // subfolders of the form android-4.2.2. We need to support both of these scenarios.
      File[] directories = buildToolsDir.listFiles(new FileFilter() {
        @Override
        public boolean accept(File pathname) {
          return pathname.isDirectory();
        }
      });

      if (directories.length == 0) {
        throw new HumanReadableException(
          Joiner.on(System.getProperty("line.separator")).join(
            "%s was empty, but should have contained a subdirectory with build tools.",
            "Install them using the Android SDK Manager (%s)."),
          buildToolsDir.getAbsolutePath(),
          new File(androidSdkDir, Joiner.on(File.separator).join("tools", "android"))
        );
      } else {
        File newestBuildToolsDir = pickNewestBuildToolsDir(ImmutableSet.copyOf(directories));
        buildToolsPath = "build-tools/" + newestBuildToolsDir.getName();
      }
    } else {
      buildToolsPath = "platform-tools";
    }

    File androidFrameworkIdlFile = new File(platformDirectory, "framework.aidl");
    File proguardJar = new File(androidSdkDir, "tools/proguard/lib/proguard.jar");
    File proguardConfig = new File(androidSdkDir, "tools/proguard/proguard-android.txt");
    File optimizedProguardConfig =
        new File(androidSdkDir, "tools/proguard/proguard-android-optimize.txt");

    return new AndroidPlatformTarget(
        name,
        androidJar,
        bootclasspathEntries,
        new File(androidSdkDir, buildToolsPath + "/aapt"),
        new File(androidSdkDir, "platform-tools/adb"),
        new File(androidSdkDir, buildToolsPath + "/aidl"),
        new File(androidSdkDir, "tools/zipalign"),
        new File(androidSdkDir, buildToolsPath + "/dx"),
        androidFrameworkIdlFile,
        proguardJar,
        proguardConfig,
        optimizedProguardConfig);
  }

  private static File pickNewestBuildToolsDir(Set<File> directories) {
    if (directories.size() == 1) {
      return Iterables.getOnlyElement(directories);
    }

    List<File> androidVersionDirectories = Lists.newArrayList();
    List<File> apiVersionDirectories = Lists.newArrayList();
    for (File dir : directories) {
      if (dir.getName().startsWith("android-")) {
        androidVersionDirectories.add(dir);
      } else {
        apiVersionDirectories.add(dir);
      }
    }

    final VersionStringComparator comparator = new VersionStringComparator();

    // This is the directory from newer downloads from http://developer.android.com/, so prefer
    // these.
    if (!androidVersionDirectories.isEmpty()) {
      Collections.sort(androidVersionDirectories, new Comparator<File>() {
        @Override
        public int compare(File a, File b) {
          String versionA = a.getName().substring("android-".length());
          String versionB = b.getName().substring("android-".length());
          return comparator.compare(versionA, versionB);
        }
      });
      // Return the last element in the list.
      return androidVersionDirectories.get(androidVersionDirectories.size() - 1);
    } else {
      Collections.sort(apiVersionDirectories, new Comparator<File>() {
        @Override
        public int compare(File a, File b) {
          String versionA = a.getName();
          String versionB = b.getName();
          return comparator.compare(versionA, versionB);
        }
      });
      // Return the last element in the list.
      return apiVersionDirectories.get(apiVersionDirectories.size() - 1);
    }
  }

  /**
   * Factory to build an AndroidPlatformTarget that corresponds to a given Google API level.
   */
  private static class AndroidWithGoogleApisFactory implements Factory {

    @Override
    public AndroidPlatformTarget newInstance(File androidSdkDir, int apiLevel) {
      String addonPath = String.format("/add-ons/addon-google_apis-google-%d/libs/", apiLevel);
      File addonDirectory = new File(androidSdkDir.getPath() + addonPath);
      String[] addonFiles;

      if (!addonDirectory.isDirectory() ||
          (addonFiles = addonDirectory.list(new AddonFilter())) == null ||
          addonFiles.length == 0) {
        throw new HumanReadableException(
            "Google APIs not found in %s.\n" +
            "Please run '%s/tools/android sdk' and select both 'SDK Platform' and " +
            "'Google APIs' under Android (API %d)",
            addonDirectory.getAbsolutePath(),
            androidSdkDir.getPath(),
            apiLevel);
      }

      ImmutableSet.Builder<String> builder = ImmutableSet.builder();

      Arrays.sort(addonFiles);
      for (String filename : addonFiles) {
        builder.add(addonPath + filename);
      }
      Set<String> additionalJarPaths = builder.build();

      return createFromDefaultDirectoryStructure(
          String.format("Google Inc.:Google APIs:%d", apiLevel),
          androidSdkDir,
          String.format("platforms/android-%d", apiLevel),
          additionalJarPaths);
    }
  }

  private static class AddonFilter implements FilenameFilter {

    @Override
    public boolean accept(File dir, String name) {
      return name.endsWith(".jar");
    }
  }
}
