Improve Android SDK and NDK mistmatch warning message (#147809)

This PR resolves #147806

- List plugin that want to be compiled against a higher Android SDK version
- List plugins that depend on a different NDK version (we don't have a way to compare them)
- Small formatting and wording improvements
- Update syntax to work for both Groovy and Kotlin
- If project uses `build.gradle.kts`, then it is mentioned in the warning message (previously always `build.gradle` was mentioned)

<img width="1209" alt="demo" src="https://github.com/flutter/flutter/assets/40357511/be3522b5-d1b4-4983-9fed-8aaa0f0bc7f7">
diff --git a/packages/flutter_tools/gradle/src/main/groovy/flutter.groovy b/packages/flutter_tools/gradle/src/main/groovy/flutter.groovy
index 5cda294..62e74a6 100644
--- a/packages/flutter_tools/gradle/src/main/groovy/flutter.groovy
+++ b/packages/flutter_tools/gradle/src/main/groovy/flutter.groovy
@@ -693,7 +693,7 @@
             if (pluginProject == null) {
                 // Plugin was not included in `settings.gradle`, but is listed in `.flutter-plugins`.
                 project.logger.error("Plugin project :${it.name} listed, but not found. Please fix your settings.gradle/settings.gradle.kts.")
-            } else if (doesSupportAndroidPlatform(pluginProject.projectDir.parentFile.path as String)) {
+            } else if (pluginSupportsAndroidPlatform(pluginProject)) {
                 // Plugin has a functioning `android` folder and is included successfully, although it's not supported.
                 // It must be configured nonetheless, to not throw an "Unresolved reference" exception.
                 configurePluginProject(it)
@@ -706,12 +706,23 @@
 
     // TODO(54566): Can remove this function and its call sites once resolved.
     /**
-     * Returns `true` if the given path contains an `android` directory
+     * Returns `true` if the given project is a plugin project having an `android` directory
      * containing a `build.gradle` or `build.gradle.kts` file.
      */
-    private Boolean doesSupportAndroidPlatform(String path) {
-        File buildGradle = new File(path, 'android' + File.separator + 'build.gradle')
-        File buildGradleKts = new File(path, 'android' + File.separator + 'build.gradle.kts')
+    private Boolean pluginSupportsAndroidPlatform(Project project) {
+        File buildGradle = new File(project.projectDir.parentFile, "android" + File.separator + "build.gradle")
+        File buildGradleKts = new File(project.projectDir.parentFile, "android" + File.separator + "build.gradle.kts")
+        return buildGradle.exists() || buildGradleKts.exists()
+    }
+
+    /**
+     * Returns the Gradle build script for the build. When both Groovy and
+     * Kotlin variants exist, then Groovy (build.gradle) is preferred over
+     * Kotlin (build.gradle.kts). This is the same behavior as Gradle 8.5.
+     */
+    private File buildGradleFile(Project project) {
+        File buildGradle = new File(project.projectDir.parentFile, "app" + File.separator + "build.gradle")
+        File buildGradleKts = new File(project.projectDir.parentFile, "app" + File.separator + "build.gradle.kts")
         if (buildGradle.exists() && buildGradleKts.exists()) {
             project.logger.error(
                 "Both build.gradle and build.gradle.kts exist, so " +
@@ -719,7 +730,7 @@
             )
         }
 
-        return buildGradle.exists() || buildGradleKts.exists()
+        return buildGradle.exists() ? buildGradle : buildGradleKts
     }
 
     /**
@@ -837,6 +848,8 @@
             String projectNdkVersion = project.android.ndkVersion ?: ndkVersionIfUnspecified
             String maxPluginNdkVersion = projectNdkVersion
             int numProcessedPlugins = getPluginList(project).size()
+            List<Tuple2<String, String>> pluginsWithHigherSdkVersion = []
+            List<Tuple2<String, String>> pluginsWithDifferentNdkVersion = []
 
             getPluginList(project).each { pluginObject ->
                 assert(pluginObject.name instanceof String)
@@ -851,17 +864,49 @@
                     if (getCompileSdkFromProject(pluginProject).isInteger()) {
                         pluginCompileSdkVersion = getCompileSdkFromProject(pluginProject) as int
                     }
+
                     maxPluginCompileSdkVersion = Math.max(pluginCompileSdkVersion, maxPluginCompileSdkVersion)
+                    if (pluginCompileSdkVersion > projectCompileSdkVersion) {
+                        pluginsWithHigherSdkVersion.add(new Tuple(pluginProject.name, pluginCompileSdkVersion))
+                    }
+
                     String pluginNdkVersion = pluginProject.android.ndkVersion ?: ndkVersionIfUnspecified
                     maxPluginNdkVersion = mostRecentSemanticVersion(pluginNdkVersion, maxPluginNdkVersion)
+                    if (pluginNdkVersion != projectNdkVersion) {
+                        pluginsWithDifferentNdkVersion.add(new Tuple(pluginProject.name, pluginNdkVersion))
+                    }
 
                     numProcessedPlugins--
                     if (numProcessedPlugins == 0) {
                         if (maxPluginCompileSdkVersion > projectCompileSdkVersion) {
-                            project.logger.error("One or more plugins require a higher Android SDK version.\nFix this issue by adding the following to ${project.projectDir}${File.separator}build.gradle:\nandroid {\n  compileSdkVersion ${maxPluginCompileSdkVersion}\n  ...\n}\n")
+                            project.logger.error("Your project is configured to compile against Android SDK $projectCompileSdkVersion, but the following plugin(s) require to be compiled against a higher Android SDK version:")
+                            for (Tuple2<String, String> pluginToCompileSdkVersion : pluginsWithHigherSdkVersion) {
+                                project.logger.error("- ${pluginToCompileSdkVersion.first} compiles against Android SDK ${pluginToCompileSdkVersion.second}")
+                            }
+                            project.logger.error("""\
+                                Fix this issue by compiling against the highest Android SDK version (they are backward compatible).
+                                Add the following to ${buildGradleFile(project).path}:
+
+                                    android {
+                                        compileSdk = ${maxPluginCompileSdkVersion}
+                                        ...
+                                    }
+                                """.stripIndent())
                         }
                         if (maxPluginNdkVersion != projectNdkVersion) {
-                            project.logger.error("One or more plugins require a higher Android NDK version.\nFix this issue by adding the following to ${project.projectDir}${File.separator}build.gradle:\nandroid {\n  ndkVersion \"${maxPluginNdkVersion}\"\n  ...\n}\n")
+                            project.logger.error("Your project is configured with Android NDK $projectNdkVersion, but the following plugin(s) depend on a different Android NDK version:")
+                            for (Tuple2<String, String> pluginToNdkVersion : pluginsWithDifferentNdkVersion) {
+                                project.logger.error("- ${pluginToNdkVersion.first} requires Android NDK ${pluginToNdkVersion.second}")
+                            }
+                            project.logger.error("""\
+                                Fix this issue by using the highest Android NDK version (they are backward compatible).
+                                Add the following to ${buildGradleFile(project).path}:
+
+                                    android {
+                                        ndkVersion = \"${maxPluginNdkVersion}\"
+                                        ...
+                                    }
+                                """.stripIndent())
                         }
                     }
                 }
diff --git a/packages/flutter_tools/test/integration.shard/android_plugin_compilesdkversion_mismatch_test.dart b/packages/flutter_tools/test/integration.shard/android_plugin_compilesdkversion_mismatch_test.dart
index 02335c4..9f753e6 100644
--- a/packages/flutter_tools/test/integration.shard/android_plugin_compilesdkversion_mismatch_test.dart
+++ b/packages/flutter_tools/test/integration.shard/android_plugin_compilesdkversion_mismatch_test.dart
@@ -75,16 +75,20 @@
 
     // Check error message is thrown
     expect(
-        result.stdout,
+        result.stderr,
         contains(
-            'Warning: The plugin test_plugin requires Android SDK version 31 or higher.'));
+            'Your project is configured to compile against Android SDK 30, but '
+            'the following plugin(s) require to be compiled against a higher Android SDK version:'));
     expect(
       result.stderr,
-      contains('One or more plugins require a higher Android SDK version.'),
+      contains('- test_plugin compiles against Android SDK 31'),
     );
     expect(
         result.stderr,
         contains(
-            'Fix this issue by adding the following to ${projectGradleFile.path}'));
+            'Fix this issue by compiling against the highest Android SDK version (they are backward compatible).'));
+    expect(
+        result.stderr,
+        contains('Add the following to ${projectGradleFile.path}:'));
   });
 }
diff --git a/packages/flutter_tools/test/integration.shard/android_plugin_ndkversion_mismatch_test.dart b/packages/flutter_tools/test/integration.shard/android_plugin_ndkversion_mismatch_test.dart
index d2eb640..93e3cfd 100644
--- a/packages/flutter_tools/test/integration.shard/android_plugin_ndkversion_mismatch_test.dart
+++ b/packages/flutter_tools/test/integration.shard/android_plugin_ndkversion_mismatch_test.dart
@@ -74,13 +74,15 @@
 
     // Check that an error message is thrown.
     expect(result.stderr, contains('''
-One or more plugins require a higher Android NDK version.
-Fix this issue by adding the following to ${projectGradleFile.path}:
-android {
-  ndkVersion "21.4.7075529"
-  ...
-}
+Your project is configured with Android NDK 21.1.6352462, but the following plugin(s) depend on a different Android NDK version:
+- test_plugin requires Android NDK 21.4.7075529
+Fix this issue by using the highest Android NDK version (they are backward compatible).
+Add the following to ${projectGradleFile.path}:
 
+    android {
+        ndkVersion = "21.4.7075529"
+        ...
+    }
 '''));
   });
 }