// Copyright 2014 The Flutter 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/process.dart';
import '../base/terminal.dart';
import '../globals.dart' as globals;
import '../project.dart';
import '../reporting/reporting.dart';
import 'gradle_utils.dart';

typedef GradleErrorTest = bool Function(String);

/// A Gradle error handled by the tool.
class GradleHandledError {
  const GradleHandledError({
    this.test,
    this.handler,
    this.eventLabel,
  });

  /// The test function.
  /// Returns [true] if the current error message should be handled.
  final GradleErrorTest test;

  /// The handler function.
  final Future<GradleBuildStatus> Function({
    String line,
    FlutterProject project,
    bool usesAndroidX,
    bool shouldBuildPluginAsAar,
  }) handler;

  /// The [BuildEvent] label is named gradle-[eventLabel].
  /// If not empty, the build event is logged along with
  /// additional metadata such as the attempt number.
  final String eventLabel;
}

/// The status of the Gradle build.
enum GradleBuildStatus {
  /// The tool cannot recover from the failure and should exit.
  exit,
  /// The tool can retry the exact same build.
  retry,
  /// The tool can build the plugins as AAR and retry the build.
  retryWithAarPlugins,
}

/// Returns a simple test function that evaluates to [true] if
/// [errorMessage] is contained in the error message.
GradleErrorTest _lineMatcher(List<String> errorMessages) {
  return (String line) {
    return errorMessages.any((String errorMessage) => line.contains(errorMessage));
  };
}

/// The list of Gradle errors that the tool can handle.
///
/// The handlers are executed in the order in which they appear in the list.
///
/// Only the first error handler for which the [test] function returns [true]
/// is handled. As a result, sort error handlers based on how strict the [test]
/// function is to eliminate false positives.
final List<GradleHandledError> gradleErrors = <GradleHandledError>[
  licenseNotAcceptedHandler,
  networkErrorHandler,
  permissionDeniedErrorHandler,
  flavorUndefinedHandler,
  r8FailureHandler,
  androidXFailureHandler,
];

// Permission defined error message.
@visibleForTesting
final GradleHandledError permissionDeniedErrorHandler = GradleHandledError(
  test: _lineMatcher(const <String>[
    'Permission denied',
  ]),
  handler: ({
    String line,
    FlutterProject project,
    bool usesAndroidX,
    bool shouldBuildPluginAsAar,
  }) async {
    globals.printStatus('$warningMark Gradle does not have execution permission.', emphasis: true);
    globals.printStatus(
      'You should change the ownership of the project directory to your user, '
      'or move the project to a directory with execute permissions.',
      indent: 4
    );
    return GradleBuildStatus.exit;
  },
  eventLabel: 'permission-denied',
);

// Gradle crashes for several known reasons when downloading that are not
// actionable by flutter.
@visibleForTesting
final GradleHandledError networkErrorHandler = GradleHandledError(
  test: _lineMatcher(const <String>[
    'java.io.FileNotFoundException: https://downloads.gradle.org',
    'java.io.IOException: Unable to tunnel through proxy',
    'java.lang.RuntimeException: Timeout of',
    'java.util.zip.ZipException: error in opening zip file',
    'javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake',
    'java.net.SocketException: Connection reset',
    'java.io.FileNotFoundException',
    'Gateway Time-out'
  ]),
  handler: ({
    String line,
    FlutterProject project,
    bool usesAndroidX,
    bool shouldBuildPluginAsAar,
  }) async {
    globals.printError(
      '$warningMark Gradle threw an error while downloading artifacts from the network. '
      'Retrying to download...'
    );
    return GradleBuildStatus.retry;
  },
  eventLabel: 'network',
);

// R8 failure.
@visibleForTesting
final GradleHandledError r8FailureHandler = GradleHandledError(
  test: _lineMatcher(const <String>[
    'com.android.tools.r8',
  ]),
  handler: ({
    String line,
    FlutterProject project,
    bool usesAndroidX,
    bool shouldBuildPluginAsAar,
  }) async {
    globals.printStatus('$warningMark The shrinker may have failed to optimize the Java bytecode.', emphasis: true);
    globals.printStatus('To disable the shrinker, pass the `--no-shrink` flag to this command.', indent: 4);
    globals.printStatus('To learn more, see: https://developer.android.com/studio/build/shrink-code', indent: 4);
    return GradleBuildStatus.exit;
  },
  eventLabel: 'r8',
);

// AndroidX failure.
//
// 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.');

@visibleForTesting
final GradleHandledError androidXFailureHandler = GradleHandledError(
  test: (String line) {
    return !androidXPluginWarningRegex.hasMatch(line) &&
           _androidXFailureRegex.hasMatch(line);
  },
  handler: ({
    String line,
    FlutterProject project,
    bool usesAndroidX,
    bool shouldBuildPluginAsAar,
  }) async {
    final bool hasPlugins = project.flutterPluginsFile.existsSync();
    if (!hasPlugins) {
      // If the app doesn't use any plugin, then it's unclear where
      // the incompatibility is coming from.
      BuildEvent(
        'gradle-android-x-failure',
        eventError: 'app-not-using-plugins',
        flutterUsage: globals.flutterUsage,
      ).send();
    }
    if (hasPlugins && !usesAndroidX) {
      // If the app isn't using AndroidX, then the app is likely using
      // a plugin already migrated to AndroidX.
      globals.printStatus(
        'AndroidX incompatibilities may have caused this build to fail. '
        'Please migrate your app to AndroidX. See https://goo.gl/CP92wY.'
      );
      BuildEvent(
        'gradle-android-x-failure',
        eventError: 'app-not-using-androidx',
        flutterUsage: globals.flutterUsage,
      ).send();
    }
    if (hasPlugins && usesAndroidX && shouldBuildPluginAsAar) {
      // This is a dependency conflict instead of an AndroidX failure since
      // by this point the app is using AndroidX, the plugins are built as
      // AARs, Jetifier translated Support libraries for AndroidX equivalents.
      BuildEvent(
        'gradle-android-x-failure',
        eventError: 'using-jetifier',
        flutterUsage: globals.flutterUsage,
      ).send();
    }
    if (hasPlugins && usesAndroidX && !shouldBuildPluginAsAar) {
      globals.printStatus(
        'The built failed likely due to AndroidX incompatibilities in a plugin. '
        'The tool is about to try using Jetfier to solve the incompatibility.'
      );
      BuildEvent(
        'gradle-android-x-failure',
        eventError: 'not-using-jetifier',
        flutterUsage: globals.flutterUsage,
      ).send();
      return GradleBuildStatus.retryWithAarPlugins;
    }
    return GradleBuildStatus.exit;
  },
  eventLabel: 'android-x',
);

/// 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.
@visibleForTesting
final GradleHandledError licenseNotAcceptedHandler = GradleHandledError(
  test: _lineMatcher(const <String>[
    'You have not accepted the license agreements of the following SDK components',
  ]),
  handler: ({
    String line,
    FlutterProject project,
    bool usesAndroidX,
    bool shouldBuildPluginAsAar,
  }) async {
    const String licenseNotAcceptedMatcher =
      r'You have not accepted the license agreements of the following SDK components:\s*\[(.+)\]';

    final RegExp licenseFailure = RegExp(licenseNotAcceptedMatcher, multiLine: true);
    assert(licenseFailure != null);
    final Match licenseMatch = licenseFailure.firstMatch(line);
    globals.printStatus(
      '$warningMark Unable to download needed Android SDK components, as the '
      'following licenses have not been accepted:\n'
      '${licenseMatch.group(1)}\n\n'
      'To resolve this, please run the following command in a Terminal:\n'
      'flutter doctor --android-licenses'
    );
    return GradleBuildStatus.exit;
  },
  eventLabel: 'license-not-accepted',
);

final RegExp _undefinedTaskPattern = RegExp(r'Task .+ not found in root project.');

final RegExp _assembleTaskPattern = RegExp(r'assemble(\S+)');

/// Handler when a flavor is undefined.
@visibleForTesting
final GradleHandledError flavorUndefinedHandler = GradleHandledError(
  test: (String line) {
    return _undefinedTaskPattern.hasMatch(line);
  },
  handler: ({
    String line,
    FlutterProject project,
    bool usesAndroidX,
    bool shouldBuildPluginAsAar,
  }) async {
    final RunResult tasksRunResult = await processUtils.run(
      <String>[
        gradleUtils.getExecutable(project),
        'app:tasks' ,
        '--all',
        '--console=auto',
      ],
      throwOnError: true,
      workingDirectory: project.android.hostAppGradleRoot.path,
      environment: gradleEnvironment,
    );
    // Extract build types and product flavors.
    final Set<String> variants = <String>{};
    for (final String task in tasksRunResult.stdout.split('\n')) {
      final Match match = _assembleTaskPattern.matchAsPrefix(task);
      if (match != null) {
        final String variant = match.group(1).toLowerCase();
        if (!variant.endsWith('test')) {
          variants.add(variant);
        }
      }
    }
    final Set<String> productFlavors = <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)) {
            productFlavors.add(variant1);
          }
        }
      }
    }
    globals.printStatus(
      '\n$warningMark  Gradle project does not define a task suitable '
      'for the requested build.'
    );
    if (productFlavors.isEmpty) {
      globals.printStatus(
        'The android/app/build.gradle file does not define '
        'any custom product flavors. '
        'You cannot use the --flavor option.'
      );
    } else {
      globals.printStatus(
        'The android/app/build.gradle file defines product '
        'flavors: ${productFlavors.join(', ')} '
        'You must specify a --flavor option to select one of them.'
      );
    }
    return GradleBuildStatus.exit;
  },
  eventLabel: 'flavor-undefined',
);
