// 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 'dart:async';

import 'package:archive/archive.dart';
import 'package:bsdiff/bsdiff.dart';
import 'package:meta/meta.dart';

import '../android/android_sdk.dart';
import '../application_package.dart';
import '../artifacts.dart';
import '../base/common.dart';
import '../base/file_system.dart';
import '../base/logger.dart';
import '../base/os.dart';
import '../base/platform.dart';
import '../base/process.dart';
import '../base/utils.dart';
import '../build_info.dart';
import '../cache.dart';
import '../convert.dart';
import '../flutter_manifest.dart';
import '../globals.dart';
import '../project.dart';
import 'android_sdk.dart';
import 'android_studio.dart';

const String gradleVersion = '4.10.2';
final RegExp _assembleTaskPattern = RegExp(r'assemble(\S+)');

GradleProject _cachedGradleProject;
String _cachedGradleExecutable;

enum FlutterPluginVersion {
  none,
  v1,
  v2,
  managed,
}

// Investigation documented in #13975 suggests the filter should be a subset
// of the impact of -q, but users insist they see the error message sometimes
// anyway.  If we can prove it really is impossible, delete the filter.
// This technically matches everything *except* the NDK message, since it's
// passed to a function that filters out all lines that don't match a filter.
final RegExp ndkMessageFilter = RegExp(r'^(?!NDK is missing a ".*" directory'
  r'|If you are not using NDK, unset the NDK variable from ANDROID_NDK_HOME or local.properties to remove this warning'
  r'|If you are using NDK, verify the ndk.dir is set to a valid NDK directory.  It is currently set to .*)');

// This regex is intentionally broad. AndroidX errors can manifest in multiple
// different ways and each one depends on the specific code config and
// filesystem paths of the project. Throwing the broadest net possible here to
// catch all known and likely cases.
//
// Example stack traces:
//
// https://github.com/flutter/flutter/issues/27226 "AAPT: error: resource android:attr/fontVariationSettings not found."
// https://github.com/flutter/flutter/issues/27106 "Android resource linking failed|Daemon: AAPT2|error: failed linking references"
// https://github.com/flutter/flutter/issues/27493 "error: cannot find symbol import androidx.annotation.NonNull;"
// https://github.com/flutter/flutter/issues/23995 "error: package android.support.annotation does not exist import android.support.annotation.NonNull;"
final RegExp androidXFailureRegex = RegExp(r'(AAPT|androidx|android\.support)');

final RegExp androidXPluginWarningRegex = RegExp(r'\*{57}'
  r"|WARNING: This version of (\w+) will break your Android build if it or its dependencies aren't compatible with AndroidX."
  r'|See https://goo.gl/CP92wY for more information on the problem and how to fix it.'
  r'|This warning prints for all Android build failures. The real root cause of the error may be unrelated.');

FlutterPluginVersion getFlutterPluginVersion(AndroidProject project) {
  final File plugin = project.hostAppGradleRoot.childFile(
      fs.path.join('buildSrc', 'src', 'main', 'groovy', 'FlutterPlugin.groovy'));
  if (plugin.existsSync()) {
    final String packageLine = plugin.readAsLinesSync().skip(4).first;
    if (packageLine == 'package io.flutter.gradle') {
      return FlutterPluginVersion.v2;
    }
    return FlutterPluginVersion.v1;
  }
  final File appGradle = project.hostAppGradleRoot.childFile(
      fs.path.join('app', 'build.gradle'));
  if (appGradle.existsSync()) {
    for (String line in appGradle.readAsLinesSync()) {
      if (line.contains(RegExp(r'apply from: .*/flutter.gradle'))) {
        return FlutterPluginVersion.managed;
      }
      if (line.contains("def flutterPluginVersion = 'managed'")) {
        return FlutterPluginVersion.managed;
      }
    }
  }
  return FlutterPluginVersion.none;
}

/// Returns the apk file created by [buildGradleProject]
Future<File> getGradleAppOut(AndroidProject androidProject) async {
  switch (getFlutterPluginVersion(androidProject)) {
    case FlutterPluginVersion.none:
      // Fall through. Pretend we're v1, and just go with it.
    case FlutterPluginVersion.v1:
      return androidProject.gradleAppOutV1File;
    case FlutterPluginVersion.managed:
      // Fall through. The managed plugin matches plugin v2 for now.
    case FlutterPluginVersion.v2:
      return fs.file((await _gradleProject()).apkDirectory.childFile('app.apk'));
  }
  return null;
}

Future<GradleProject> _gradleProject() async {
  _cachedGradleProject ??= await _readGradleProject();
  return _cachedGradleProject;
}

/// Runs `gradlew dependencies`, ensuring that dependencies are resolved and
/// potentially downloaded.
Future<void> checkGradleDependencies() async {
  final Status progress = logger.startProgress('Ensuring gradle dependencies are up to date...', timeout: kSlowOperation);
  final FlutterProject flutterProject = await FlutterProject.current();
  final String gradle = await _ensureGradle(flutterProject);
  await runCheckedAsync(
    <String>[gradle, 'dependencies'],
    workingDirectory: flutterProject.android.hostAppGradleRoot.path,
    environment: _gradleEnv,
  );
  androidSdk.reinitialize();
  progress.stop();
}

// Note: Dependencies are resolved and possibly downloaded as a side-effect
// of calculating the app properties using Gradle. This may take minutes.
Future<GradleProject> _readGradleProject() async {
  final FlutterProject flutterProject = await FlutterProject.current();
  final String gradle = await _ensureGradle(flutterProject);
  updateLocalProperties(project: flutterProject);
  final Status status = logger.startProgress('Resolving dependencies...', timeout: kSlowOperation);
  GradleProject project;
  try {
    final RunResult propertiesRunResult = await runCheckedAsync(
      <String>[gradle, 'app:properties'],
      workingDirectory: flutterProject.android.hostAppGradleRoot.path,
      environment: _gradleEnv,
    );
    final RunResult tasksRunResult = await runCheckedAsync(
      <String>[gradle, 'app:tasks', '--all', '--console=auto'],
      workingDirectory: flutterProject.android.hostAppGradleRoot.path,
      environment: _gradleEnv,
    );
    project = GradleProject.fromAppProperties(propertiesRunResult.stdout, tasksRunResult.stdout);
  } catch (exception) {
    if (getFlutterPluginVersion(flutterProject.android) == FlutterPluginVersion.managed) {
      status.cancel();
      // Handle known exceptions. This will exit if handled.
      handleKnownGradleExceptions(exception.toString());

      // Print a general Gradle error and exit.
      printError('* Error running Gradle:\n$exception\n');
      throwToolExit('Please review your Gradle project setup in the android/ folder.');
    }
    // Fall back to the default
    project = GradleProject(
      <String>['debug', 'profile', 'release'],
      <String>[], flutterProject.android.gradleAppOutV1Directory,
        flutterProject.android.gradleAppBundleOutV1Directory,
    );
  }
  status.stop();
  return project;
}

void handleKnownGradleExceptions(String exceptionString) {
  // Handle Gradle error thrown when Gradle needs to download additional
  // Android SDK components (e.g. Platform Tools), and the license
  // for that component has not been accepted.
  const String matcher =
    r'You have not accepted the license agreements of the following SDK components:'
    r'\s*\[(.+)\]';
  final RegExp licenseFailure = RegExp(matcher, multiLine: true);
  final Match licenseMatch = licenseFailure.firstMatch(exceptionString);
  if (licenseMatch != null) {
    final String missingLicenses = licenseMatch.group(1);
    final String errorMessage =
      '\n\n* Error running Gradle:\n'
      'Unable to download needed Android SDK components, as the following licenses have not been accepted:\n'
      '$missingLicenses\n\n'
      'To resolve this, please run the following command in a Terminal:\n'
      'flutter doctor --android-licenses';
    throwToolExit(errorMessage);
  }
}

String _locateGradlewExecutable(Directory directory) {
  final File gradle = directory.childFile(
    platform.isWindows ? 'gradlew.bat' : 'gradlew',
  );

  if (gradle.existsSync()) {
    os.makeExecutable(gradle);
    return gradle.absolute.path;
  } else {
    return null;
  }
}

Future<String> _ensureGradle(FlutterProject project) async {
  _cachedGradleExecutable ??= await _initializeGradle(project);
  return _cachedGradleExecutable;
}

// Note: Gradle may be bootstrapped and possibly downloaded as a side-effect
// of validating the Gradle executable. This may take several seconds.
Future<String> _initializeGradle(FlutterProject project) async {
  final Directory android = project.android.hostAppGradleRoot;
  final Status status = logger.startProgress('Initializing gradle...', timeout: kSlowOperation);
  String gradle = _locateGradlewExecutable(android);
  if (gradle == null) {
    injectGradleWrapper(android);
    gradle = _locateGradlewExecutable(android);
  }
  if (gradle == null)
    throwToolExit('Unable to locate gradlew script');
  printTrace('Using gradle from $gradle.');
  // Validates the Gradle executable by asking for its version.
  // Makes Gradle Wrapper download and install Gradle distribution, if needed.
  await runCheckedAsync(<String>[gradle, '-v'], environment: _gradleEnv);
  status.stop();
  return gradle;
}

/// Injects the Gradle wrapper into the specified directory.
void injectGradleWrapper(Directory directory) {
  copyDirectorySync(cache.getArtifactDirectory('gradle_wrapper'), directory);
  _locateGradlewExecutable(directory);
  final File propertiesFile = directory.childFile(fs.path.join('gradle', 'wrapper', 'gradle-wrapper.properties'));
  if (!propertiesFile.existsSync()) {
    propertiesFile.writeAsStringSync('''
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\\://services.gradle.org/distributions/gradle-$gradleVersion-all.zip
''', flush: true,
    );
  }
}

/// Overwrite local.properties in the specified Flutter project's Android
/// sub-project, if needed.
///
/// If [requireAndroidSdk] is true (the default) and no Android SDK is found,
/// this will fail with a [ToolExit].
void updateLocalProperties({
  @required FlutterProject project,
  BuildInfo buildInfo,
  bool requireAndroidSdk = true,
}) {
  if (requireAndroidSdk) {
    _exitIfNoAndroidSdk();
  }

  final File localProperties = project.android.localPropertiesFile;
  bool changed = false;

  SettingsFile settings;
  if (localProperties.existsSync()) {
    settings = SettingsFile.parseFromFile(localProperties);
  } else {
    settings = SettingsFile();
    changed = true;
  }

  void changeIfNecessary(String key, String value) {
    if (settings.values[key] != value) {
      if (value == null) {
        settings.values.remove(key);
      } else {
        settings.values[key] = value;
      }
      changed = true;
    }
  }

  final FlutterManifest manifest = project.manifest;

  if (androidSdk != null)
    changeIfNecessary('sdk.dir', escapePath(androidSdk.directory));

  changeIfNecessary('flutter.sdk', escapePath(Cache.flutterRoot));

  if (buildInfo != null) {
    changeIfNecessary('flutter.buildMode', buildInfo.modeName);
    final String buildName = validatedBuildNameForPlatform(TargetPlatform.android_arm, buildInfo.buildName ?? manifest.buildName);
    changeIfNecessary('flutter.versionName', buildName);
    final String buildNumber = validatedBuildNumberForPlatform(TargetPlatform.android_arm, buildInfo.buildNumber ?? manifest.buildNumber);
    changeIfNecessary('flutter.versionCode', buildNumber?.toString());
  }

  if (changed)
    settings.writeContents(localProperties);
}

/// Writes standard Android local properties to the specified [properties] file.
///
/// Writes the path to the Android SDK, if known.
void writeLocalProperties(File properties) {
  final SettingsFile settings = SettingsFile();
  if (androidSdk != null) {
    settings.values['sdk.dir'] = escapePath(androidSdk.directory);
  }
  settings.writeContents(properties);
}

/// Throws a ToolExit, if the path to the Android SDK is not known.
void _exitIfNoAndroidSdk() {
  if (androidSdk == null) {
    throwToolExit('Unable to locate Android SDK. Please run `flutter doctor` for more details.');
  }
}

Future<void> buildGradleProject({
  @required FlutterProject project,
  @required BuildInfo buildInfo,
  @required String target,
  @required bool isBuildingBundle,
}) async {
  // Update the local.properties file with the build mode, version name and code.
  // FlutterPlugin v1 reads local.properties to determine build mode. Plugin v2
  // uses the standard Android way to determine what to build, but we still
  // update local.properties, in case we want to use it in the future.
  // Version name and number are provided by the pubspec.yaml file
  // and can be overwritten with flutter build command.
  // The default Gradle script reads the version name and number
  // from the local.properties file.
  updateLocalProperties(project: project, buildInfo: buildInfo);

  final String gradle = await _ensureGradle(project);

  switch (getFlutterPluginVersion(project.android)) {
    case FlutterPluginVersion.none:
      // Fall through. Pretend it's v1, and just go for it.
    case FlutterPluginVersion.v1:
      return _buildGradleProjectV1(project, gradle);
    case FlutterPluginVersion.managed:
      // Fall through. Managed plugin builds the same way as plugin v2.
    case FlutterPluginVersion.v2:
      return _buildGradleProjectV2(project, gradle, buildInfo, target, isBuildingBundle);
  }
}

Future<void> _buildGradleProjectV1(FlutterProject project, String gradle) async {
  // Run 'gradlew build'.
  final Status status = logger.startProgress(
    'Running \'gradlew build\'...',
    timeout: kSlowOperation,
    multilineOutput: true,
  );
  final int exitCode = await runCommandAndStreamOutput(
    <String>[fs.file(gradle).absolute.path, 'build'],
    workingDirectory: project.android.hostAppGradleRoot.path,
    allowReentrantFlutter: true,
    environment: _gradleEnv,
  );
  status.stop();

  if (exitCode != 0)
    throwToolExit('Gradle build failed: $exitCode', exitCode: exitCode);

  printStatus('Built ${fs.path.relative(project.android.gradleAppOutV1File.path)}.');
}

Future<void> _buildGradleProjectV2(
  FlutterProject flutterProject,
  String gradle,
  BuildInfo buildInfo,
  String target,
  bool isBuildingBundle,
) async {
  final GradleProject project = await _gradleProject();

  String assembleTask;

  if (isBuildingBundle) {
    assembleTask = project.bundleTaskFor(buildInfo);
  } else {
    assembleTask = project.assembleTaskFor(buildInfo);
  }

  if (assembleTask == null) {
    printError('');
    printError('The Gradle project does not define a task suitable for the requested build.');
    if (!project.buildTypes.contains(buildInfo.modeName)) {
      printError('Review the android/app/build.gradle file and ensure it defines a ${buildInfo.modeName} build type.');
    } else {
      if (project.productFlavors.isEmpty) {
        printError('The android/app/build.gradle file does not define any custom product flavors.');
        printError('You cannot use the --flavor option.');
      } else {
        printError('The android/app/build.gradle file defines product flavors: ${project.productFlavors.join(', ')}');
        printError('You must specify a --flavor option to select one of them.');
      }
      throwToolExit('Gradle build aborted.');
    }
  }
  final Status status = logger.startProgress(
    'Running Gradle task \'$assembleTask\'...',
    timeout: kSlowOperation,
    multilineOutput: true,
  );
  final String gradlePath = fs.file(gradle).absolute.path;
  final List<String> command = <String>[gradlePath];
  if (logger.isVerbose) {
    command.add('-Pverbose=true');
  } else {
    command.add('-q');
  }
  if (artifacts is LocalEngineArtifacts) {
    final LocalEngineArtifacts localEngineArtifacts = artifacts;
    printTrace('Using local engine: ${localEngineArtifacts.engineOutPath}');
    command.add('-PlocalEngineOut=${localEngineArtifacts.engineOutPath}');
  }
  if (target != null) {
    command.add('-Ptarget=$target');
  }
  assert(buildInfo.trackWidgetCreation != null);
  command.add('-Ptrack-widget-creation=${buildInfo.trackWidgetCreation}');
  if (buildInfo.compilationTraceFilePath != null)
    command.add('-Pcompilation-trace-file=${buildInfo.compilationTraceFilePath}');
  if (buildInfo.createPatch)
    command.add('-Ppatch=true');
  if (buildInfo.extraFrontEndOptions != null)
    command.add('-Pextra-front-end-options=${buildInfo.extraFrontEndOptions}');
  if (buildInfo.extraGenSnapshotOptions != null)
    command.add('-Pextra-gen-snapshot-options=${buildInfo.extraGenSnapshotOptions}');
  if (buildInfo.fileSystemRoots != null && buildInfo.fileSystemRoots.isNotEmpty)
    command.add('-Pfilesystem-roots=${buildInfo.fileSystemRoots.join('|')}');
  if (buildInfo.fileSystemScheme != null)
    command.add('-Pfilesystem-scheme=${buildInfo.fileSystemScheme}');
  if (buildInfo.buildSharedLibrary && androidSdk.ndk != null) {
    command.add('-Pbuild-shared-library=true');
  }
  if (buildInfo.targetPlatform != null)
    command.add('-Ptarget-platform=${getNameForTargetPlatform(buildInfo.targetPlatform)}');

  command.add(assembleTask);
  bool potentialAndroidXFailure = false;
  final int exitCode = await runCommandAndStreamOutput(
    command,
    workingDirectory: flutterProject.android.hostAppGradleRoot.path,
    allowReentrantFlutter: true,
    environment: _gradleEnv,
    // TODO(mklim): if AndroidX warnings are no longer required, this
    // mapFunction and all its associated variabled can be replaced with just
    // `filter: ndkMessagefilter`.
    mapFunction: (String line) {
      final bool isAndroidXPluginWarning = androidXPluginWarningRegex.hasMatch(line);
      if (!isAndroidXPluginWarning && androidXFailureRegex.hasMatch(line)) {
        potentialAndroidXFailure = true;
      }
      // Always print the full line in verbose mode.
      if (logger.isVerbose) {
        return line;
      } else if (isAndroidXPluginWarning || !ndkMessageFilter.hasMatch(line)) {
        return null;
      }

      return line;
    },
  );
  status.stop();

  if (exitCode != 0) {
    if (potentialAndroidXFailure) {
      printError('*******************************************************************************************');
      printError('The Gradle failure may have been because of AndroidX incompatibilities in this Flutter app.');
      printError('See https://goo.gl/CP92wY for more information on the problem and how to fix it.');
      printError('*******************************************************************************************');
    }
    throwToolExit('Gradle task $assembleTask failed with exit code $exitCode', exitCode: exitCode);
  }

  if(!isBuildingBundle) {
    final File apkFile = _findApkFile(project, buildInfo);
    if (apkFile == null)
      throwToolExit('Gradle build failed to produce an Android package.');
    // Copy the APK to app.apk, so `flutter run`, `flutter install`, etc. can find it.
    apkFile.copySync(project.apkDirectory.childFile('app.apk').path);

    printTrace('calculateSha: ${project.apkDirectory}/app.apk');
    final File apkShaFile = project.apkDirectory.childFile('app.apk.sha1');
    apkShaFile.writeAsStringSync(calculateSha(apkFile));

    String appSize;
    if (buildInfo.mode == BuildMode.debug) {
      appSize = '';
    } else {
      appSize = ' (${getSizeAsMB(apkFile.lengthSync())})';
    }
    printStatus('Built ${fs.path.relative(apkFile.path)}$appSize.');

    if (buildInfo.createBaseline) {
      // Save baseline apk for generating dynamic patches in later builds.
      final AndroidApk package = AndroidApk.fromApk(apkFile);
      final Directory baselineDir = fs.directory(buildInfo.baselineDir);
      final File baselineApkFile = baselineDir.childFile('${package.versionCode}.apk');
      baselineApkFile.parent.createSync(recursive: true);
      apkFile.copySync(baselineApkFile.path);
      printStatus('Saved baseline package ${baselineApkFile.path}.');
    }

    if (buildInfo.createPatch) {
      final AndroidApk package = AndroidApk.fromApk(apkFile);
      final Directory baselineDir = fs.directory(buildInfo.baselineDir);
      final File baselineApkFile = baselineDir.childFile('${package.versionCode}.apk');
      if (!baselineApkFile.existsSync())
        throwToolExit('Error: Could not find baseline package ${baselineApkFile.path}.');

      printStatus('Found baseline package ${baselineApkFile.path}.');
      printStatus('Creating dynamic patch...');
      final Archive newApk = ZipDecoder().decodeBytes(apkFile.readAsBytesSync());
      final Archive oldApk = ZipDecoder().decodeBytes(baselineApkFile.readAsBytesSync());

      final Archive update = Archive();
      for (ArchiveFile newFile in newApk) {
        if (!newFile.isFile)
          continue;

        // Ignore changes to signature manifests.
        if (newFile.name.startsWith('META-INF/'))
          continue;

        final ArchiveFile oldFile = oldApk.findFile(newFile.name);
        if (oldFile != null && oldFile.crc32 == newFile.crc32)
          continue;

        // Only allow certain changes.
        if (!newFile.name.startsWith('assets/') &&
            !(buildInfo.usesAot && newFile.name.endsWith('.so')))
          throwToolExit("Error: Dynamic patching doesn't support changes to ${newFile.name}.");

        final String name = newFile.name;
        if (name.contains('_snapshot_') || name.endsWith('.so')) {
          final List<int> diff = bsdiff(oldFile.content, newFile.content);
          final int ratio = 100 * diff.length ~/ newFile.content.length;
          printStatus('Deflated $name by ${ratio == 0 ? 99 : 100 - ratio}%');
          update.addFile(ArchiveFile(name + '.bzdiff40', diff.length, diff));
        } else {
          update.addFile(ArchiveFile(name, newFile.content.length, newFile.content));
        }
      }

      File updateFile;
      if (buildInfo.patchNumber != null) {
        updateFile = fs.directory(buildInfo.patchDir)
            .childFile('${package.versionCode}-${buildInfo.patchNumber}.zip');
      } else {
        updateFile = fs.directory(buildInfo.patchDir)
            .childFile('${package.versionCode}.zip');
      }

      if (update.files.isEmpty) {
        printStatus('No changes detected, creating rollback patch.');
      }

      final List<String> checksumFiles = <String>[
        'assets/isolate_snapshot_data',
        'assets/isolate_snapshot_instr',
        'assets/flutter_assets/isolate_snapshot_data',
      ];

      int baselineChecksum = 0;
      for (String fn in checksumFiles) {
        final ArchiveFile oldFile = oldApk.findFile(fn);
        if (oldFile != null)
          baselineChecksum = getCrc32(oldFile.content, baselineChecksum);
      }
      if (baselineChecksum == 0)
        throwToolExit('Error: Could not find baseline VM snapshot.');

      final Map<String, dynamic> manifest = <String, dynamic>{
        'baselineChecksum': baselineChecksum,
        'buildNumber': package.versionCode,
      };

      if (buildInfo.patchNumber != null) {
        manifest.addAll(<String, dynamic>{
          'patchNumber': buildInfo.patchNumber,
        });
      }

      const JsonEncoder encoder = JsonEncoder.withIndent('  ');
      final String manifestJson = encoder.convert(manifest);
      update.addFile(ArchiveFile('manifest.json', manifestJson.length, manifestJson.codeUnits));

      updateFile.parent.createSync(recursive: true);
      updateFile.writeAsBytesSync(ZipEncoder().encode(update), flush: true);
      final String patchSize = getSizeAsMB(updateFile.lengthSync());
      printStatus('Created dynamic patch ${updateFile.path} ($patchSize).');
    }
  } else {
    final File bundleFile = _findBundleFile(project, buildInfo);
    if (bundleFile == null)
      throwToolExit('Gradle build failed to produce an Android bundle package.');
    // Copy the bundle to app.aab, so `flutter run`, `flutter install`, etc. can find it.
    bundleFile.copySync(project.bundleDirectory
        .childFile('app.aab')
        .path);

    printTrace('calculateSha: ${project.bundleDirectory}/app.aab');
    final File bundleShaFile = project.bundleDirectory.childFile('app.aab.sha1');
    bundleShaFile.writeAsStringSync(calculateSha(bundleFile));

    String appSize;
    if (buildInfo.mode == BuildMode.debug) {
      appSize = '';
    } else {
      appSize = ' (${getSizeAsMB(bundleFile.lengthSync())})';
    }
    printStatus('Built ${fs.path.relative(bundleFile.path)}$appSize.');
  }
}

File _findApkFile(GradleProject project, BuildInfo buildInfo) {
  final String apkFileName = project.apkFileFor(buildInfo);
  if (apkFileName == null)
    return null;
  File apkFile = fs.file(fs.path.join(project.apkDirectory.path, apkFileName));
  if (apkFile.existsSync())
    return apkFile;
  final String modeName = camelCase(buildInfo.modeName);
  apkFile = fs.file(fs.path.join(project.apkDirectory.path, modeName, apkFileName));
  if (apkFile.existsSync())
    return apkFile;
  if (buildInfo.flavor != null) {
    // Android Studio Gradle plugin v3 adds flavor to path.
    apkFile = fs.file(fs.path.join(project.apkDirectory.path, buildInfo.flavor, modeName, apkFileName));
    if (apkFile.existsSync())
      return apkFile;
  }
  return null;
}

File _findBundleFile(GradleProject project, BuildInfo buildInfo) {
  final String bundleFileName = project.bundleFileFor(buildInfo);

  if (bundleFileName == null)
    return null;
  File bundleFile = fs.file(fs.path.join(project.bundleDirectory.path, bundleFileName));
  if (bundleFile.existsSync()) {
    return bundleFile;
  }
  final String modeName = camelCase(buildInfo.modeName);
  bundleFile = fs.file(fs.path.join(project.bundleDirectory.path, modeName, bundleFileName));
  if (bundleFile.existsSync())
    return bundleFile;
  if (buildInfo.flavor != null) {
    // Android Studio Gradle plugin v3 adds the flavor to the path. For the bundle the folder name is the flavor plus the mode name.
    bundleFile = fs.file(fs.path.join(project.bundleDirectory.path, buildInfo.flavor + modeName, bundleFileName));
    if (bundleFile.existsSync())
      return bundleFile;
  }
  return null;
}

Map<String, String> get _gradleEnv {
  final Map<String, String> env = Map<String, String>.from(platform.environment);
  if (javaPath != null) {
    // Use java bundled with Android Studio.
    env['JAVA_HOME'] = javaPath;
  }
  return env;
}

class GradleProject {
  GradleProject(this.buildTypes, this.productFlavors, this.apkDirectory, this.bundleDirectory);

  factory GradleProject.fromAppProperties(String properties, String tasks) {
    // Extract build directory.
    final String buildDir = properties
        .split('\n')
        .firstWhere((String s) => s.startsWith('buildDir: '))
        .substring('buildDir: '.length)
        .trim();

    // Extract build types and product flavors.
    final Set<String> variants = Set<String>();
    for (String s in tasks.split('\n')) {
      final Match match = _assembleTaskPattern.matchAsPrefix(s);
      if (match != null) {
        final String variant = match.group(1).toLowerCase();
        if (!variant.endsWith('test'))
          variants.add(variant);
      }
    }
    final Set<String> buildTypes = Set<String>();
    final Set<String> productFlavors = Set<String>();
    for (final String variant1 in variants) {
      for (final String variant2 in variants) {
        if (variant2.startsWith(variant1) && variant2 != variant1) {
          final String buildType = variant2.substring(variant1.length);
          if (variants.contains(buildType)) {
            buildTypes.add(buildType);
            productFlavors.add(variant1);
          }
        }
      }
    }
    if (productFlavors.isEmpty)
      buildTypes.addAll(variants);
    return GradleProject(
      buildTypes.toList(),
      productFlavors.toList(),
      fs.directory(fs.path.join(buildDir, 'outputs', 'apk')),
      fs.directory(fs.path.join(buildDir, 'outputs', 'bundle')),
    );
  }

  final List<String> buildTypes;
  final List<String> productFlavors;
  final Directory apkDirectory;
  final Directory bundleDirectory;

  String _buildTypeFor(BuildInfo buildInfo) {
    final String modeName = camelCase(buildInfo.modeName);
    if (buildTypes.contains(modeName.toLowerCase()))
      return modeName;
    return null;
  }

  String _productFlavorFor(BuildInfo buildInfo) {
    if (buildInfo.flavor == null)
      return productFlavors.isEmpty ? '' : null;
    else if (productFlavors.contains(buildInfo.flavor))
      return buildInfo.flavor;
    else
      return null;
  }

  String assembleTaskFor(BuildInfo buildInfo) {
    final String buildType = _buildTypeFor(buildInfo);
    final String productFlavor = _productFlavorFor(buildInfo);
    if (buildType == null || productFlavor == null)
      return null;
    return 'assemble${toTitleCase(productFlavor)}${toTitleCase(buildType)}';
  }

  String apkFileFor(BuildInfo buildInfo) {
    final String buildType = _buildTypeFor(buildInfo);
    final String productFlavor = _productFlavorFor(buildInfo);
    if (buildType == null || productFlavor == null)
      return null;
    final String flavorString = productFlavor.isEmpty ? '' : '-' + productFlavor;
    return 'app$flavorString-$buildType.apk';
  }

  String bundleTaskFor(BuildInfo buildInfo) {
    final String buildType = _buildTypeFor(buildInfo);
    final String productFlavor = _productFlavorFor(buildInfo);
    if (buildType == null || productFlavor == null)
      return null;
    return 'bundle${toTitleCase(productFlavor)}${toTitleCase(buildType)}';
  }

  String bundleFileFor(BuildInfo buildInfo) {
    // For app bundle all bundle names are called as app.aab. Product flavors
    // & build types are differentiated as folders, where the aab will be added.
    return 'app.aab';
  }
}
