/*
 * Copyright 2013-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.facebook.buck.io.ProjectFilesystem;
import com.facebook.buck.util.PropertyFinder;
import com.facebook.buck.util.HumanReadableException;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableCollection;

import java.io.IOException;
import java.nio.file.Path;
import java.util.Objects;
import java.util.StringTokenizer;

/**
 * Utility class used for resolving the location of Android specific directories.
 */
public class DefaultAndroidDirectoryResolver implements AndroidDirectoryResolver {
  private final ProjectFilesystem projectFilesystem;
  private final Optional<String> targetNdkVersion;
  private final PropertyFinder propertyFinder;

  private final Supplier<Optional<Path>> sdkSupplier;
  private final Supplier<Optional<Path>> ndkSupplier;

  public DefaultAndroidDirectoryResolver(
      ProjectFilesystem projectFilesystem,
      Optional<String> targetNdkVersion,
      PropertyFinder propertyFinder) {
    this.projectFilesystem = projectFilesystem;
    this.targetNdkVersion = targetNdkVersion;
    this.propertyFinder = propertyFinder;

    this.sdkSupplier =
        Suppliers.memoize(new Supplier<Optional<Path>>() {
          @Override
          public Optional<Path> get() {
            return getSdkPathFromSdkDir();
          }
        });

    this.ndkSupplier =
        Suppliers.memoize(new Supplier<Optional<Path>>() {
          @Override
          public Optional<Path> get() {
            return getNdkPathFromNdkRepository().or(getNdkPathFromNdkDir());
          }
        });
  }

  @Override
  public Optional<Path> findAndroidSdkDirSafe() {
    return sdkSupplier.get();
  }

  @Override
  public Path findAndroidSdkDir() {
    Optional<Path> androidSdkDir = findAndroidSdkDirSafe();
    Preconditions.checkState(androidSdkDir.isPresent(),
        "Android SDK could not be find.  Set the environment variable ANDROID_SDK to point to " +
            "your Android SDK.");
    return androidSdkDir.get();
  }

  @Override
  public Optional<Path> findAndroidNdkDir() {
    return ndkSupplier.get();
  }

  @Override
  public Optional<String> getNdkVersion() {
    Optional<Path> ndkPath = findAndroidNdkDir();
    if (!ndkPath.isPresent()) {
      return Optional.absent();
    }
    return findNdkVersionFromPath(ndkPath.get());
  }

  private Optional<String> findNdkVersionFromPath(Path ndkPath) {
    Path releaseVersion =  ndkPath.resolve("RELEASE.TXT");
    Optional<String> contents = projectFilesystem.readFirstLineFromFile(releaseVersion);

    if (contents.isPresent()) {
      return Optional.of(new StringTokenizer(contents.get()).nextToken());
    }
    return Optional.absent();
  }

  private Optional<Path> getSdkPathFromSdkDir() {
    Optional<Path> androidSdkDir =
        propertyFinder.findDirectoryByPropertiesThenEnvironmentVariable(
            "sdk.dir",
            "ANDROID_SDK",
            "ANDROID_HOME");
    if (androidSdkDir.isPresent()) {
      Preconditions.checkArgument(androidSdkDir.get().toFile().isDirectory(),
          "The location of your Android SDK %s must be a directory",
          androidSdkDir.get());
    }
    return androidSdkDir;
  }

  private Optional<Path> getNdkPathFromNdkDir() {
    Optional<Path> path = propertyFinder.findDirectoryByPropertiesThenEnvironmentVariable(
        "ndk.dir",
        "ANDROID_NDK");

    if (path.isPresent()) {
      Path ndkPath = path.get();
      Optional<String> ndkVersionOptional = findNdkVersionFromPath(ndkPath);
      if (!ndkVersionOptional.isPresent()) {
        throw new HumanReadableException(
            "Failed to read NDK version from %s", ndkPath);
      } else {
        String ndkVersion = ndkVersionOptional.get();
        if (targetNdkVersion.isPresent() && !targetNdkVersion.get().equals(ndkVersion)) {
          throw new HumanReadableException(
              "Supported NDK version is %s but Buck is configured to use %s with " +
                  "ndk.dir or ANDROID_NDK",
              targetNdkVersion.get(),
              ndkVersion);
        }
      }
    }
    return path;
  }

  private Optional<Path> getNdkPathFromNdkRepository() {
    Optional<Path> repositoryPathOptional =
        propertyFinder.findDirectoryByPropertiesThenEnvironmentVariable(
            "ndk.repository",
            "ANDROID_NDK_REPOSITORY");

    Optional<Path> path = Optional.absent();

    if (repositoryPathOptional.isPresent()) {
      Path repositoryPath = repositoryPathOptional.get();

      ImmutableCollection<Path> repositoryPathContents;
      try {
        repositoryPathContents = projectFilesystem.getDirectoryContents(repositoryPath);
      } catch (IOException e) {
        throw new HumanReadableException(
            e,
            "Failed to read the Android NDK repository directory: %s",
            repositoryPath);
      }

      String newestVersion = "";
      for (Path potentialNdkPath : repositoryPathContents) {
        if (potentialNdkPath.toFile().isDirectory()) {
          Optional<String> ndkVersion = findNdkVersionFromPath(potentialNdkPath);
          // For each directory found, first check to see if it is in fact something we
          // believe to be a NDK directory.  If it is, check to see if we have a
          // target version and if this NDK directory matches it.  If not, choose the
          // newest version.
          //
          // It is possible to collapse this all into one if statement, but it is
          // significantly harder to grok.
          if (ndkVersion.isPresent()) {
            if (targetNdkVersion.isPresent()) {
              if (targetNdkVersion.get().equals(ndkVersion.get())) {
                return Optional.of(potentialNdkPath);
              }
            } else if (ndkVersion.get().compareTo(newestVersion) > 0) {
              path = Optional.of(potentialNdkPath);
              newestVersion = ndkVersion.get();
            }
          }
        }
      }
      if (!path.isPresent()) {
        throw new HumanReadableException(
            "Couldn't find a valid NDK under %s", repositoryPath);
      }
    }
    return path;
  }

  @Override
  public boolean equals(Object other) {
    if (this == other) {
      return true;
    }

    if (!(other instanceof DefaultAndroidDirectoryResolver)) {
      return false;
    }

    DefaultAndroidDirectoryResolver that = (DefaultAndroidDirectoryResolver) other;

    return
        Objects.equals(projectFilesystem, that.projectFilesystem) &&
        Objects.equals(targetNdkVersion, that.targetNdkVersion) &&
        Objects.equals(propertyFinder, that.propertyFinder) &&
        Objects.equals(findAndroidNdkDir(), that.findAndroidNdkDir());
  }

  @Override
  public int hashCode() {
    return Objects.hash(projectFilesystem, targetNdkVersion, propertyFinder);
  }
}
