// 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/file_system.dart';
import '../../base/project_migrator.dart';
import '../../base/version.dart';
import '../../project.dart';
import '../android_studio.dart';
import '../gradle_utils.dart';
import '../java.dart';

// Android Studio 2022.2 "Flamingo" is the first to bundle a Java 17 JDK.
// Previous versions bundled a Java 11 JDK.
@visibleForTesting
final Version androidStudioFlamingo = Version(2022, 2, 0);
@visibleForTesting
const String gradleVersion7_6_1 = r'7.6.1';

// String that can be placed in the gradle-wrapper.properties to opt out of this
// migrator.
@visibleForTesting
const String optOutFlag = 'NoFlutterGradleWrapperUpgrade';
// Only the major version matters.
final Version flamingoBundledJava = Version(17, 0, 0);

// These gradle versions were chosen because they
// 1. Were output by 'flutter create' at some point in flutter's history and
// 2. Are less than 7.3, the lowest supported gradle version for JDK 17
const List<String> gradleVersionsToUpgradeFrom =
    <String>['5.6.2', '6.7'];

// Define log messages as constants to re-use in testing.
@visibleForTesting
const String gradleWrapperNotFound =
    'gradle-wrapper.properties not found, skipping Gradle-Java version compatibility check.';
@visibleForTesting
const String androidStudioNotFound =
    'Android Studio version could not be detected, '
    'skipping Gradle-Java version compatibility check.';
@visibleForTesting
const String androidStudioVersionBelowFlamingo =
    'Version of Android Studio is less than Flamingo (the first impacted version),'
    ' no migration attempted.';
@visibleForTesting
const String javaVersionNot17 =
    'Version of Java is different than impacted version, no migration attempted.';
@visibleForTesting
const String javaVersionNotFound =
    'Version of Java not found, no migration attempted.';
@visibleForTesting
const String conflictDetected = 'Conflict detected between versions of Android Studio '
    'and Gradle, upgrading Gradle version from current to 7.4';
@visibleForTesting
const String gradleVersionNotFound = 'Failed to parse Gradle version from distribution url, '
    'skipping Gradle-Java version compatibility check.';
@visibleForTesting
const String optOutFlagEnabled = 'Skipping Android Studio Java-Gradle compatibility '
    "because opt out flag: '$optOutFlag' is enabled in gradle-wrapper.properties file.";
@visibleForTesting
const String errorWhileMigrating = 'Encountered an error while attempting Gradle-Java '
    'version compatibility check, skipping migration attempt. Error was: ';


/// Migrate to a newer version of Gradle when the existing one does not support
/// the version of Java provided by the detected Android Studio version.
///
/// For more info see the Gradle-Java compatibility matrix:
/// https://docs.gradle.org/current/userguide/compatibility.html
class AndroidStudioJavaGradleConflictMigration extends ProjectMigrator {
  AndroidStudioJavaGradleConflictMigration(
    super.logger,
    {required AndroidProject project,
    AndroidStudio? androidStudio,
    required Java? java,
  }) : _gradleWrapperPropertiesFile = getGradleWrapperFile(project.hostAppGradleRoot),
       _androidStudio = androidStudio,
       _java = java;

  final File _gradleWrapperPropertiesFile;
  final AndroidStudio? _androidStudio;
  final Java? _java;

  @override
  Future<void> migrate() async {
    try {
      if (!_gradleWrapperPropertiesFile.existsSync()) {
        logger.printTrace(gradleWrapperNotFound);
        return;
      }

      if (_androidStudio == null || _androidStudio.version == null) {
        logger.printTrace(androidStudioNotFound);
        return;
      } else if (_androidStudio.version!.major < androidStudioFlamingo.major) {
        logger.printTrace(androidStudioVersionBelowFlamingo);
        return;
      }

      if (_java?.version == null) {
        logger.printTrace(javaVersionNotFound);
        return;
      }

      if (_java!.version!.major != flamingoBundledJava.major) {
        logger.printTrace(javaVersionNot17);
        return;
      }

      processFileLines(_gradleWrapperPropertiesFile);
    } on Exception catch (e) {
      logger.printTrace(errorWhileMigrating + e.toString());
    } on Error catch (e) {
      logger.printTrace(errorWhileMigrating + e.toString());
    }
  }

  @override
  String migrateFileContents(String fileContents) {
    if (fileContents.contains(optOutFlag)) {
      logger.printTrace(optOutFlagEnabled);
      return fileContents;
    }
    final RegExpMatch? gradleDistributionUrl = gradleOrgVersionMatch.firstMatch(fileContents);
    if (gradleDistributionUrl == null
        || gradleDistributionUrl.groupCount < 1
        || gradleDistributionUrl[1] == null) {
      logger.printTrace(gradleVersionNotFound);
      return fileContents;
    }
    final String existingVersionString = gradleDistributionUrl[1]!;
    if (gradleVersionsToUpgradeFrom.contains(existingVersionString)) {
      logger.printStatus('Conflict detected between Android Studio Java version and Gradle version, '
          'upgrading Gradle version from $existingVersionString to $gradleVersion7_6_1.');
      final String? gradleDistributionUrlString = gradleDistributionUrl.group(0);
      if (gradleDistributionUrlString != null) {
        final String upgradedDistributionUrl =
          gradleDistributionUrlString.replaceAll(existingVersionString, gradleVersion7_6_1);
        fileContents = fileContents.replaceFirst(gradleOrgVersionMatch, upgradedDistributionUrl);
      } else {
        logger.printTrace(gradleVersionNotFound);
      }
    }
    return fileContents;
  }
}
