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