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

import com.facebook.buck.command.Build;
import com.facebook.buck.event.BuckEventBus;
import com.facebook.buck.rules.DependencyGraph;
import com.facebook.buck.util.AndroidPlatformTarget;
import com.facebook.buck.util.HumanReadableException;
import com.facebook.buck.util.ProjectFilesystem;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;

import org.kohsuke.args4j.Option;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
import java.util.StringTokenizer;

import javax.annotation.Nullable;

public abstract class AbstractCommandOptions {

  @VisibleForTesting static final String HELP_LONG_ARG = "--help";

  /**
   * This value should never be read. {@link VerbosityParser} should be used instead.
   * args4j requires that all options that could be passed in are listed as fields, so we include
   * this field so that {@code --verbose} is universally available to all commands.
   */
  @Option(
      name = VerbosityParser.VERBOSE_LONG_ARG,
      aliases = { VerbosityParser.VERBOSE_SHORT_ARG },
      usage = "Specify a number between 1 and 10.")
  @SuppressWarnings("unused")
  private int verbosityLevel = -1;

  @Option(
      name = "--no-cache",
      usage = "Whether to ignore the [cache] declared in .buckconfig.")
  private boolean noCache = false;

  @Option(
      name = HELP_LONG_ARG,
      usage = "Prints the available options and exits.")
  private boolean help = false;

  private final BuckConfig buckConfig;

  @Nullable // Lazily loaded via getCommandLineBuildTargetNormalizer().
  private CommandLineBuildTargetNormalizer commandLineBuildTargetNormalizer;

  AbstractCommandOptions(BuckConfig buckConfig) {
    this.buckConfig = Preconditions.checkNotNull(buckConfig);
  }

  /** @return {code true} if the {@code [cache]} in {@code .buckconfig} should be ignored. */
  public boolean isNoCache() {
    return noCache;
  }

  protected BuckConfig getBuckConfig() {
    return buckConfig;
  }

  public Iterable<String> getDefaultIncludes() {
    return this.buckConfig.getDefaultIncludes();
  }

  public boolean showHelp() {
    return help;
  }

  protected CommandLineBuildTargetNormalizer getCommandLineBuildTargetNormalizer() {
    if (commandLineBuildTargetNormalizer == null) {
      commandLineBuildTargetNormalizer = new CommandLineBuildTargetNormalizer(buckConfig);
    }
    return commandLineBuildTargetNormalizer;
  }

  /** @return androidSdkDir */
  public static Optional<File> findAndroidSdkDir() {
    Optional<File> androidSdkDir = findDirectoryByPropertiesThenEnvironmentVariable(
        "sdk.dir", "ANDROID_SDK", "ANDROID_HOME");
    if (androidSdkDir.isPresent()) {
      Preconditions.checkArgument(androidSdkDir.get().isDirectory(),
          "The location of your Android SDK %s must be a directory",
          androidSdkDir.get());
    }
    return androidSdkDir;
  }

  /** @return androidNdkDir */
  protected Optional<File> findAndroidNdkDir(ProjectFilesystem projectFilesystem) {
    Optional<File> path =
      findDirectoryByPropertiesThenEnvironmentVariable("ndk.dir", "ANDROID_NDK");
    if (path.isPresent()) {
      validateNdkVersion(projectFilesystem, path.get());
    }
    return path;
  }

  @VisibleForTesting
  void validateNdkVersion(ProjectFilesystem projectFilesystem, File ndkPath) {
    Optional<String> minVersion = this.buckConfig.getMinimumNdkVersion();
    Optional<String> maxVersion = this.buckConfig.getMaximumNdkVersion();

    if (minVersion.isPresent() && maxVersion.isPresent()) {
      File versionPath = new File(ndkPath, "RELEASE.TXT");
      Optional<String> contents = projectFilesystem.readFirstLineFromFile(versionPath);
      String version;

      if (contents.isPresent()) {
        version = new StringTokenizer(contents.get()).nextToken();
      } else {
        throw new HumanReadableException(
            "Failed to read NDK version from %s", versionPath.getPath());
      }

      // Example forms: r8, r8b, r9
      if (version.length() < 2) {
        throw new HumanReadableException("Invalid NDK version: %s", version);
      }

      if (version.compareTo(minVersion.get()) < 0 || version.compareTo(maxVersion.get()) > 0) {
        throw new HumanReadableException(
            "Supported NDK versions are between %s and %s but Buck is configured to use %s from %s",
            minVersion.get(),
            maxVersion.get(),
            version,
            ndkPath.getAbsolutePath());
      }
    } else if (minVersion.isPresent() || maxVersion.isPresent()) {
      throw new HumanReadableException(
          "Either both min_version and max_version are provided or neither are");
    }
  }

  /**
   * @param propertyName The name of the property to look for in local.properties.
   * @param environmentVariables The name of the environment variables to try.
   * @return If present, the value is confirmed to be a directory.
   */
  public static Optional<File> findDirectoryByPropertiesThenEnvironmentVariable(
      String propertyName,
      String... environmentVariables) {
    // First, try to find a value in local.properties using the specified propertyName.
    String dirPath = null;
    File propertiesFile = new File("local.properties");
    if (propertiesFile.exists()) {
      Properties localProperties = new Properties();
      try {
        localProperties.load(new FileReader(propertiesFile));
      } catch (IOException e) {
        throw new RuntimeException(
            "Failed reading properties from " + propertiesFile.getAbsolutePath(),
            e);
      }
      dirPath = localProperties.getProperty(propertyName);
    }

    // If dirPath is not set, try each of the environment variables, in order, to find it.
    for (String environmentVariable : environmentVariables) {
      if (dirPath == null) {
        dirPath = System.getenv(environmentVariable);
      } else {
        break;
      }
    }

    // If a dirPath was found, verify that it maps to a directory before returning it.
    if (dirPath == null) {
      return Optional.absent();
    } else {
      File directory = new File(dirPath);
      if (!directory.isDirectory()) {
        throw new RuntimeException(
            directory.getAbsolutePath() + " was not a directory when trying to find " +
              propertyName);
      }
      return Optional.of(directory);
    }
  }

  protected Optional<AndroidPlatformTarget> findAndroidPlatformTarget(
      DependencyGraph dependencyGraph, BuckEventBus eventBus) {
    return Build.findAndroidPlatformTarget(dependencyGraph, findAndroidSdkDir(), eventBus);
  }
}
