// 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
  void migrate() {
    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;
  }
}
