// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:meta/meta.dart';

import '../base/common.dart';
import '../base/context.dart';
import '../base/file_system.dart';
import '../base/io.dart' show ProcessResult;
import '../base/os.dart';
import '../base/platform.dart';
import '../base/process.dart';
import '../base/process_manager.dart';
import '../base/version.dart';
import '../convert.dart';
import '../globals.dart';
import 'android_studio.dart' as android_studio;

AndroidSdk get androidSdk => context.get<AndroidSdk>();

const String kAndroidHome = 'ANDROID_HOME';
const String kAndroidSdkRoot = 'ANDROID_SDK_ROOT';

// Android SDK layout:

// $ANDROID_HOME/platform-tools/adb

// $ANDROID_HOME/build-tools/19.1.0/aapt, dx, zipalign
// $ANDROID_HOME/build-tools/22.0.1/aapt
// $ANDROID_HOME/build-tools/23.0.2/aapt
// $ANDROID_HOME/build-tools/24.0.0-preview/aapt
// $ANDROID_HOME/build-tools/25.0.2/apksigner

// $ANDROID_HOME/platforms/android-22/android.jar
// $ANDROID_HOME/platforms/android-23/android.jar
// $ANDROID_HOME/platforms/android-N/android.jar

final RegExp _numberedAndroidPlatformRe = RegExp(r'^android-([0-9]+)$');
final RegExp _sdkVersionRe = RegExp(r'^ro.build.version.sdk=([0-9]+)$');

/// The minimum Android SDK version we support.
const int minimumAndroidSdkVersion = 25;

/// Locate ADB. Prefer to use one from an Android SDK, if we can locate that.
/// This should be used over accessing androidSdk.adbPath directly because it
/// will work for those users who have Android Platform Tools installed but
/// not the full SDK.
String getAdbPath([ AndroidSdk existingSdk ]) {
  if (existingSdk?.adbPath != null)
    return existingSdk.adbPath;

  final AndroidSdk sdk = AndroidSdk.locateAndroidSdk();

  if (sdk?.latestVersion == null) {
    return os.which('adb')?.path;
  } else {
    return sdk.adbPath;
  }
}

/// Locate 'emulator'. Prefer to use one from an Android SDK, if we can locate that.
/// This should be used over accessing androidSdk.emulatorPath directly because it
/// will work for those users who have Android Tools installed but
/// not the full SDK.
String getEmulatorPath([ AndroidSdk existingSdk ]) {
  return existingSdk?.emulatorPath ??
    AndroidSdk.locateAndroidSdk()?.emulatorPath;
}

/// Locate the path for storing AVD emulator images. Returns null if none found.
String getAvdPath() {

  final List<String> searchPaths = <String>[
    platform.environment['ANDROID_AVD_HOME'],
  ];

  if (platform.environment['HOME'] != null)
    searchPaths.add(fs.path.join(platform.environment['HOME'], '.android', 'avd'));

  if (platform.isWindows) {
    final String homeDrive = platform.environment['HOMEDRIVE'];
    final String homePath = platform.environment['HOMEPATH'];

    if (homeDrive != null && homePath != null) {
      // Can't use path.join for HOMEDRIVE/HOMEPATH
      // https://github.com/dart-lang/path/issues/37
      final String home = homeDrive + homePath;
      searchPaths.add(fs.path.join(home, '.android', 'avd'));
    }
  }

  return searchPaths.where((String p) => p != null).firstWhere(
    (String p) => fs.directory(p).existsSync(),
    orElse: () => null,
  );
}

/// Locate 'avdmanager'. Prefer to use one from an Android SDK, if we can locate that.
/// This should be used over accessing androidSdk.avdManagerPath directly because it
/// will work for those users who have Android Tools installed but
/// not the full SDK.
String getAvdManagerPath([ AndroidSdk existingSdk ]) {
  return existingSdk?.avdManagerPath ??
    AndroidSdk.locateAndroidSdk()?.avdManagerPath;
}

class AndroidNdkSearchError {
  AndroidNdkSearchError(this.reason);

  /// The message explaining why NDK was not found.
  final String reason;
}

class AndroidNdk {
  AndroidNdk._(this.directory, this.compiler, this.compilerArgs);

  /// The path to the NDK.
  final String directory;

  /// The path to the NDK compiler.
  final String compiler;

  /// The mandatory arguments to the NDK compiler.
  final List<String> compilerArgs;

  /// Locate NDK within the given SDK or throw [AndroidNdkSearchError].
  static AndroidNdk locateNdk(String androidHomeDir) {
    if (androidHomeDir == null) {
      throw AndroidNdkSearchError('Can not locate NDK because no SDK is found');
    }

    String findBundle(String androidHomeDir) {
      final String ndkDirectory = fs.path.join(androidHomeDir, 'ndk-bundle');
      if (!fs.isDirectorySync(ndkDirectory)) {
        throw AndroidNdkSearchError('Can not locate ndk-bundle, tried: $ndkDirectory');
      }
      return ndkDirectory;
    }

    // Returns list that contains toolchain bin folder and compiler binary name.
    List<String> findToolchainAndCompiler(String ndkDirectory) {
      String directory;
      if (platform.isLinux) {
        directory = 'linux-x86_64';
      } else if (platform.isMacOS) {
        directory = 'darwin-x86_64';
      } else {
        throw AndroidNdkSearchError('Only Linux and macOS are supported');
      }

      final String toolchainBin = fs.path.join(ndkDirectory,
          'toolchains', 'arm-linux-androideabi-4.9', 'prebuilt', directory,
          'bin');
      final String ndkCompiler = fs.path.join(toolchainBin,
          'arm-linux-androideabi-gcc');
      if (!fs.isFileSync(ndkCompiler)) {
        throw AndroidNdkSearchError('Can not locate GCC binary, tried $ndkCompiler');
      }

      return <String>[toolchainBin, ndkCompiler];
    }

    List<String> findSysroot(String ndkDirectory) {
      // If entity represents directory with name android-<version> that
      // contains arch-arm subdirectory then returns version, otherwise
      // returns null.
      int toPlatformVersion(FileSystemEntity entry) {
        if (entry is! Directory) {
          return null;
        }

        if (!fs.isDirectorySync(fs.path.join(entry.path, 'arch-arm'))) {
          return null;
        }

        final String name = fs.path.basename(entry.path);

        const String platformPrefix = 'android-';
        if (!name.startsWith(platformPrefix)) {
          return null;
        }

        return int.tryParse(name.substring(platformPrefix.length));
      }

      final String platformsDir = fs.path.join(ndkDirectory, 'platforms');
      final List<int> versions = fs
          .directory(platformsDir)
          .listSync()
          .map(toPlatformVersion)
          .where((int version) => version != null)
          .toList(growable: false);
      versions.sort();

      final int suitableVersion = versions
          .firstWhere((int version) => version >= 9, orElse: () => null);
      if (suitableVersion == null) {
        throw AndroidNdkSearchError('Can not locate a suitable platform ARM sysroot (need android-9 or newer), tried to look in $platformsDir');
      }

      final String armPlatform = fs.path.join(ndkDirectory, 'platforms',
          'android-$suitableVersion', 'arch-arm');
      return <String>['--sysroot', armPlatform];
    }

    int findNdkMajorVersion(String ndkDirectory) {
      final String propertiesFile = fs.path.join(ndkDirectory, 'source.properties');
      if (!fs.isFileSync(propertiesFile)) {
        throw AndroidNdkSearchError('Can not establish ndk-bundle version: $propertiesFile not found');
      }

      // Parse source.properties: each line has Key = Value format.
      final Iterable<String> propertiesFileLines = fs.file(propertiesFile)
          .readAsStringSync()
          .split('\n')
          .map<String>((String line) => line.trim())
          .where((String line) => line.isNotEmpty);
      final Map<String, String> properties = <String, String>{};
      for (String line in propertiesFileLines) {
        final List<String> parts = line.split(' = ');
        if (parts.length == 2) {
          properties[parts[0]] = parts[1];
        } else {
          printError('Malformed line in ndk source.properties: "$line".');
        }
      }

      if (!properties.containsKey('Pkg.Revision')) {
        throw AndroidNdkSearchError('Can not establish ndk-bundle version: $propertiesFile does not contain Pkg.Revision');
      }

      // Extract major version from Pkg.Revision property which looks like <ndk-version>.x.y.
      return int.parse(properties['Pkg.Revision'].split('.').first);
    }

    final String ndkDir = findBundle(androidHomeDir);
    final int ndkVersion = findNdkMajorVersion(ndkDir);
    final List<String> ndkToolchainAndCompiler = findToolchainAndCompiler(ndkDir);
    final String ndkToolchain = ndkToolchainAndCompiler[0];
    final String ndkCompiler = ndkToolchainAndCompiler[1];
    final List<String> ndkCompilerArgs = findSysroot(ndkDir);
    if (ndkVersion >= 18) {
      // Newer versions of NDK use clang instead of gcc, which falls back to
      // system linker instead of using toolchain linker. Force clang to
      // use appropriate linker by passing -fuse-ld=<path-to-ld> command line
      // flag.
      final String ndkLinker = fs.path.join(ndkToolchain, 'arm-linux-androideabi-ld');
      if (!fs.isFileSync(ndkLinker)) {
        throw AndroidNdkSearchError('Can not locate linker binary, tried $ndkLinker');
      }
      ndkCompilerArgs.add('-fuse-ld=$ndkLinker');
    }
    return AndroidNdk._(ndkDir, ndkCompiler, ndkCompilerArgs);
  }

  /// Returns a descriptive message explaining why NDK can not be found within
  /// the given SDK.
  static String explainMissingNdk(String androidHomeDir) {
    try {
      locateNdk(androidHomeDir);
      return 'Unexpected error: found NDK on the second try';
    } on AndroidNdkSearchError catch (e) {
      return e.reason;
    }
  }
}

class AndroidSdk {
  AndroidSdk(this.directory, [this.ndk]) {
    reinitialize();
  }

  static const String _javaHomeEnvironmentVariable = 'JAVA_HOME';
  static const String _javaExecutable = 'java';

  /// The path to the Android SDK.
  final String directory;

  /// Android NDK (can be `null`).
  final AndroidNdk ndk;

  List<AndroidSdkVersion> _sdkVersions;
  AndroidSdkVersion _latestVersion;

  /// Whether the `platform-tools` directory exists in the Android SDK.
  ///
  /// It is possible to have an Android SDK folder that is missing this with
  /// the expectation that it will be downloaded later, e.g. by gradle or the
  /// sdkmanager. The [licensesAvailable] property should be used to determine
  /// whether the licenses are at least possibly accepted.
  bool get platformToolsAvailable => fs.directory(fs.path.join(directory, 'platform-tools')).existsSync();

  /// Whether the `licenses` directory exists in the Android SDK.
  ///
  /// The existence of this folder normally indicates that the SDK licenses have
  /// been accepted, e.g. via the sdkmanager, Android Studio, or by copying them
  /// from another workstation such as in CI scenarios. If these files are valid
  /// gradle or the sdkmanager will be able to download and use other parts of
  /// the SDK on demand.
  bool get licensesAvailable => fs.directory(fs.path.join(directory, 'licenses')).existsSync();

  static AndroidSdk locateAndroidSdk() {
    String findAndroidHomeDir() {
      String androidHomeDir;
      if (config.containsKey('android-sdk')) {
        androidHomeDir = config.getValue('android-sdk');
      } else if (platform.environment.containsKey(kAndroidHome)) {
        androidHomeDir = platform.environment[kAndroidHome];
      } else if (platform.environment.containsKey(kAndroidSdkRoot)) {
        androidHomeDir = platform.environment[kAndroidSdkRoot];
      } else if (platform.isLinux) {
        if (homeDirPath != null)
          androidHomeDir = fs.path.join(homeDirPath, 'Android', 'Sdk');
      } else if (platform.isMacOS) {
        if (homeDirPath != null)
          androidHomeDir = fs.path.join(homeDirPath, 'Library', 'Android', 'sdk');
      } else if (platform.isWindows) {
        if (homeDirPath != null)
          androidHomeDir = fs.path.join(homeDirPath, 'AppData', 'Local', 'Android', 'sdk');
      }

      if (androidHomeDir != null) {
        if (validSdkDirectory(androidHomeDir))
          return androidHomeDir;
        if (validSdkDirectory(fs.path.join(androidHomeDir, 'sdk')))
          return fs.path.join(androidHomeDir, 'sdk');
      }

      // in build-tools/$version/aapt
      final List<File> aaptBins = os.whichAll('aapt');
      for (File aaptBin in aaptBins) {
        // Make sure we're using the aapt from the SDK.
        aaptBin = fs.file(aaptBin.resolveSymbolicLinksSync());
        final String dir = aaptBin.parent.parent.parent.path;
        if (validSdkDirectory(dir))
          return dir;
      }

      // in platform-tools/adb
      final List<File> adbBins = os.whichAll('adb');
      for (File adbBin in adbBins) {
        // Make sure we're using the adb from the SDK.
        adbBin = fs.file(adbBin.resolveSymbolicLinksSync());
        final String dir = adbBin.parent.parent.path;
        if (validSdkDirectory(dir))
          return dir;
      }

      return null;
    }

    final String androidHomeDir = findAndroidHomeDir();
    if (androidHomeDir == null) {
      // No dice.
      printTrace('Unable to locate an Android SDK.');
      return null;
    }

    // Try to find the NDK compiler. If we can't find it, it's also ok.
    AndroidNdk ndk;
    try {
      ndk = AndroidNdk.locateNdk(androidHomeDir);
    } on AndroidNdkSearchError {
      // Ignore AndroidNdkSearchError's but don't ignore any other
      // exceptions.
    }

    return AndroidSdk(androidHomeDir, ndk);
  }

  static bool validSdkDirectory(String dir) {
    return sdkDirectoryHasLicenses(dir) || sdkDirectoryHasPlatformTools(dir);
  }

  static bool sdkDirectoryHasPlatformTools(String dir) {
    return fs.isDirectorySync(fs.path.join(dir, 'platform-tools'));
  }

  static bool sdkDirectoryHasLicenses(String dir) {
    return fs.isDirectorySync(fs.path.join(dir, 'licenses'));
  }

  List<AndroidSdkVersion> get sdkVersions => _sdkVersions;

  AndroidSdkVersion get latestVersion => _latestVersion;

  String get adbPath => getPlatformToolsPath(platform.isWindows ? 'adb.exe' : 'adb');

  String get emulatorPath => getEmulatorPath();

  String get avdManagerPath => getAvdManagerPath();

  Directory get _platformsDir => fs.directory(fs.path.join(directory, 'platforms'));

  Iterable<Directory> get _platforms {
    Iterable<Directory> platforms = <Directory>[];
    if (_platformsDir.existsSync()) {
      platforms = _platformsDir
        .listSync()
        .whereType<Directory>();
    }
    return platforms;
  }

  /// Validate the Android SDK. This returns an empty list if there are no
  /// issues; otherwise, it returns a list of issues found.
  List<String> validateSdkWellFormed() {
    if (adbPath == null || !processManager.canRun(adbPath))
      return <String>['Android SDK file not found: ${adbPath ?? 'adb'}.'];

    if (sdkVersions.isEmpty || latestVersion == null) {
      final StringBuffer msg = StringBuffer('No valid Android SDK platforms found in ${_platformsDir.path}.');
      if (_platforms.isEmpty) {
        msg.write(' Directory was empty.');
      } else {
        msg.write(' Candidates were:\n');
        msg.write(_platforms
          .map((Directory dir) => '  - ${dir.basename}')
          .join('\n'));
      }
      return <String>[msg.toString()];
    }

    return latestVersion.validateSdkWellFormed();
  }

  String getPlatformToolsPath(String binaryName) {
    final String path = fs.path.join(directory, 'platform-tools', binaryName);
    if (fs.file(path).existsSync())
      return path;
    return null;
  }

  String getEmulatorPath() {
    final String binaryName = platform.isWindows ? 'emulator.exe' : 'emulator';
    // Emulator now lives inside "emulator" but used to live inside "tools" so
    // try both.
    final List<String> searchFolders = <String>['emulator', 'tools'];
    for (final String folder in searchFolders) {
      final String path = fs.path.join(directory, folder, binaryName);
      if (fs.file(path).existsSync())
        return path;
    }
    return null;
  }

  String getAvdManagerPath() {
    final String binaryName = platform.isWindows ? 'avdmanager.bat' : 'avdmanager';
    final String path = fs.path.join(directory, 'tools', 'bin', binaryName);
    if (fs.file(path).existsSync())
      return path;
    return null;
  }

  /// Sets up various paths used internally.
  ///
  /// This method should be called in a case where the tooling may have updated
  /// SDK artifacts, such as after running a gradle build.
  void reinitialize() {
    List<Version> buildTools = <Version>[]; // 19.1.0, 22.0.1, ...

    final Directory buildToolsDir = fs.directory(fs.path.join(directory, 'build-tools'));
    if (buildToolsDir.existsSync()) {
      buildTools = buildToolsDir
        .listSync()
        .map((FileSystemEntity entity) {
          try {
            return Version.parse(entity.basename);
          } catch (error) {
            return null;
          }
        })
        .where((Version version) => version != null)
        .toList();
    }

    // Match up platforms with the best corresponding build-tools.
    _sdkVersions = _platforms.map<AndroidSdkVersion>((Directory platformDir) {
      final String platformName = platformDir.basename;
      int platformVersion;

      try {
        final Match numberedVersion = _numberedAndroidPlatformRe.firstMatch(platformName);
        if (numberedVersion != null) {
          platformVersion = int.parse(numberedVersion.group(1));
        } else {
          final String buildProps = platformDir.childFile('build.prop').readAsStringSync();
          final String versionString = const LineSplitter()
              .convert(buildProps)
              .map<Match>(_sdkVersionRe.firstMatch)
              .firstWhere((Match match) => match != null)
              .group(1);
          platformVersion = int.parse(versionString);
        }
      } catch (error) {
        return null;
      }

      Version buildToolsVersion = Version.primary(buildTools.where((Version version) {
        return version.major == platformVersion;
      }).toList());

      buildToolsVersion ??= Version.primary(buildTools);

      if (buildToolsVersion == null)
        return null;

      return AndroidSdkVersion._(
        this,
        sdkLevel: platformVersion,
        platformName: platformName,
        buildToolsVersion: buildToolsVersion,
      );
    }).where((AndroidSdkVersion version) => version != null).toList();

    _sdkVersions.sort();

    _latestVersion = _sdkVersions.isEmpty ? null : _sdkVersions.last;
  }

  /// Returns the filesystem path of the Android SDK manager tool or null if not found.
  String get sdkManagerPath {
    return fs.path.join(directory, 'tools', 'bin', 'sdkmanager');
  }

  /// First try Java bundled with Android Studio, then sniff JAVA_HOME, then fallback to PATH.
  static String findJavaBinary() {

    if (android_studio.javaPath != null)
      return fs.path.join(android_studio.javaPath, 'bin', 'java');

    final String javaHomeEnv = platform.environment[_javaHomeEnvironmentVariable];
    if (javaHomeEnv != null) {
      // Trust JAVA_HOME.
      return fs.path.join(javaHomeEnv, 'bin', 'java');
    }

    // MacOS specific logic to avoid popping up a dialog window.
    // See: http://stackoverflow.com/questions/14292698/how-do-i-check-if-the-java-jdk-is-installed-on-mac.
    if (platform.isMacOS) {
      try {
        final String javaHomeOutput = runCheckedSync(<String>['/usr/libexec/java_home'], hideStdout: true);
        if (javaHomeOutput != null) {
          final List<String> javaHomeOutputSplit = javaHomeOutput.split('\n');
          if ((javaHomeOutputSplit != null) && (javaHomeOutputSplit.isNotEmpty)) {
            final String javaHome = javaHomeOutputSplit[0].trim();
            return fs.path.join(javaHome, 'bin', 'java');
          }
        }
      } catch (_) { /* ignore */ }
    }

    // Fallback to PATH based lookup.
    return os.which(_javaExecutable)?.path;
  }

  Map<String, String> _sdkManagerEnv;
  /// Returns an environment with the Java folder added to PATH for use in calling
  /// Java-based Android SDK commands such as sdkmanager and avdmanager.
  Map<String, String> get sdkManagerEnv {
    if (_sdkManagerEnv == null) {
      // If we can locate Java, then add it to the path used to run the Android SDK manager.
      _sdkManagerEnv = <String, String>{};
      final String javaBinary = findJavaBinary();
      if (javaBinary != null) {
        _sdkManagerEnv['PATH'] =
            fs.path.dirname(javaBinary) + os.pathVarSeparator + platform.environment['PATH'];
      }
    }
    return _sdkManagerEnv;
  }

  /// Returns the version of the Android SDK manager tool or null if not found.
  String get sdkManagerVersion {
    if (!processManager.canRun(sdkManagerPath))
      throwToolExit('Android sdkmanager not found. Update to the latest Android SDK to resolve this.');
    final ProcessResult result = processManager.runSync(<String>[sdkManagerPath, '--version'], environment: sdkManagerEnv);
    if (result.exitCode != 0) {
      printTrace('sdkmanager --version failed: exitCode: ${result.exitCode} stdout: ${result.stdout} stderr: ${result.stderr}');
      return null;
    }
    return result.stdout.trim();
  }

  @override
  String toString() => 'AndroidSdk: $directory';
}

class AndroidSdkVersion implements Comparable<AndroidSdkVersion> {
  AndroidSdkVersion._(
    this.sdk, {
    @required this.sdkLevel,
    @required this.platformName,
    @required this.buildToolsVersion,
  }) : assert(sdkLevel != null),
       assert(platformName != null),
       assert(buildToolsVersion != null);

  final AndroidSdk sdk;
  final int sdkLevel;
  final String platformName;
  final Version buildToolsVersion;

  String get buildToolsVersionName => buildToolsVersion.toString();

  String get androidJarPath => getPlatformsPath('android.jar');

  String get aaptPath => getBuildToolsPath('aapt');

  List<String> validateSdkWellFormed() {
    if (_exists(androidJarPath) != null)
      return <String>[_exists(androidJarPath)];

    if (_canRun(aaptPath) != null)
      return <String>[_canRun(aaptPath)];

    return <String>[];
  }

  String getPlatformsPath(String itemName) {
    return fs.path.join(sdk.directory, 'platforms', platformName, itemName);
  }

  String getBuildToolsPath(String binaryName) {
    return fs.path.join(sdk.directory, 'build-tools', buildToolsVersionName, binaryName);
  }

  @override
  int compareTo(AndroidSdkVersion other) => sdkLevel - other.sdkLevel;

  @override
  String toString() => '[${sdk.directory}, SDK version $sdkLevel, build-tools $buildToolsVersionName]';

  String _exists(String path) {
    if (!fs.isFileSync(path))
      return 'Android SDK file not found: $path.';
    return null;
  }

  String _canRun(String path) {
    if (!processManager.canRun(path))
      return 'Android SDK file not found: $path.';
    return null;
  }
}
