// Copyright 2013 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 'dart:convert';

import 'package:args/command_runner.dart';
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_plugin_tools/src/common/core.dart';
import 'package:flutter_plugin_tools/src/update_dependency_command.dart';
import 'package:http/http.dart' as http;
import 'package:http/testing.dart';
import 'package:pubspec_parse/pubspec_parse.dart';
import 'package:test/test.dart';

import 'mocks.dart';
import 'util.dart';

void main() {
  FileSystem fileSystem;
  late Directory packagesDir;
  late RecordingProcessRunner processRunner;
  late CommandRunner<void> runner;
  Future<http.Response> Function(http.Request request)? mockHttpResponse;

  setUp(() {
    fileSystem = MemoryFileSystem();
    processRunner = RecordingProcessRunner();
    packagesDir = createPackagesDirectory(fileSystem: fileSystem);
    final UpdateDependencyCommand command = UpdateDependencyCommand(
      packagesDir,
      processRunner: processRunner,
      httpClient:
          MockClient((http.Request request) => mockHttpResponse!(request)),
    );

    runner = CommandRunner<void>(
        'update_dependency_command', 'Test for update-dependency command.');
    runner.addCommand(command);
  });

  /// Adds a dummy 'dependencies:' entries for [dependency] to [package].
  void addDependency(RepositoryPackage package, String dependency,
      {String version = '^1.0.0'}) {
    final List<String> lines = package.pubspecFile.readAsLinesSync();
    final int dependenciesStartIndex = lines.indexOf('dependencies:');
    assert(dependenciesStartIndex != -1);
    lines.insert(dependenciesStartIndex + 1, '  $dependency: $version');
    package.pubspecFile.writeAsStringSync(lines.join('\n'));
  }

  /// Adds a 'dev_dependencies:' section with an entry for [dependency] to
  /// [package].
  void addDevDependency(RepositoryPackage package, String dependency,
      {String version = '^1.0.0'}) {
    final String originalContent = package.pubspecFile.readAsStringSync();
    package.pubspecFile.writeAsStringSync('''
$originalContent

dev_dependencies:
  $dependency: $version
''');
  }

  test('throws if no target is provided', () async {
    Error? commandError;
    final List<String> output = await runCapturingPrint(
        runner, <String>['update-dependency'], errorHandler: (Error e) {
      commandError = e;
    });

    expect(commandError, isA<ToolExit>());
    expect(
      output,
      containsAllInOrder(<Matcher>[
        contains('Exactly one of the target flags must be provided:'),
      ]),
    );
  });

  test('throws if multiple dependencies specified', () async {
    Error? commandError;
    final List<String> output = await runCapturingPrint(runner, <String>[
      'update-dependency',
      '--pub-package',
      'target_package',
      '--android-dependency',
      'gradle'
    ], errorHandler: (Error e) {
      commandError = e;
    });

    expect(commandError, isA<ToolExit>());
    expect(
      output,
      containsAllInOrder(<Matcher>[
        contains('Exactly one of the target flags must be provided:'),
      ]),
    );
  });

  group('pub dependencies', () {
    test('throws if no version is given for an unpublished target', () async {
      mockHttpResponse = (http.Request request) async {
        return http.Response('', 404);
      };

      Error? commandError;
      final List<String> output = await runCapturingPrint(runner, <String>[
        'update-dependency',
        '--pub-package',
        'target_package'
      ], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('target_package does not exist on pub'),
        ]),
      );
    });

    test('skips if there is no dependency', () async {
      createFakePackage('a_package', packagesDir, examples: <String>[]);

      final List<String> output = await runCapturingPrint(runner, <String>[
        'update-dependency',
        '--pub-package',
        'target_package',
        '--version',
        '1.5.0'
      ]);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('SKIPPING: Does not depend on target_package'),
        ]),
      );
    });

    test('skips if the dependency is already the target version', () async {
      final RepositoryPackage package =
          createFakePackage('a_package', packagesDir, examples: <String>[]);
      addDependency(package, 'target_package', version: '^1.5.0');

      final List<String> output = await runCapturingPrint(runner, <String>[
        'update-dependency',
        '--pub-package',
        'target_package',
        '--version',
        '1.5.0'
      ]);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('SKIPPING: Already depends on ^1.5.0'),
        ]),
      );
    });

    test('logs updates', () async {
      final RepositoryPackage package =
          createFakePackage('a_package', packagesDir, examples: <String>[]);
      addDependency(package, 'target_package');

      final List<String> output = await runCapturingPrint(runner, <String>[
        'update-dependency',
        '--pub-package',
        'target_package',
        '--version',
        '1.5.0'
      ]);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Updating to "^1.5.0"'),
        ]),
      );
    });

    test('updates normal dependency', () async {
      final RepositoryPackage package =
          createFakePackage('a_package', packagesDir, examples: <String>[]);
      addDependency(package, 'target_package');

      await runCapturingPrint(runner, <String>[
        'update-dependency',
        '--pub-package',
        'target_package',
        '--version',
        '1.5.0'
      ]);

      final Dependency? dep =
          package.parsePubspec().dependencies['target_package'];
      expect(dep, isA<HostedDependency>());
      expect((dep! as HostedDependency).version.toString(), '^1.5.0');
    });

    test('updates dev dependency', () async {
      final RepositoryPackage package =
          createFakePackage('a_package', packagesDir, examples: <String>[]);
      addDevDependency(package, 'target_package');

      await runCapturingPrint(runner, <String>[
        'update-dependency',
        '--pub-package',
        'target_package',
        '--version',
        '1.5.0'
      ]);

      final Dependency? dep =
          package.parsePubspec().devDependencies['target_package'];
      expect(dep, isA<HostedDependency>());
      expect((dep! as HostedDependency).version.toString(), '^1.5.0');
    });

    test('updates dependency in example', () async {
      final RepositoryPackage package =
          createFakePackage('a_package', packagesDir);
      final RepositoryPackage example = package.getExamples().first;
      addDevDependency(example, 'target_package');

      await runCapturingPrint(runner, <String>[
        'update-dependency',
        '--pub-package',
        'target_package',
        '--version',
        '1.5.0'
      ]);

      final Dependency? dep =
          example.parsePubspec().devDependencies['target_package'];
      expect(dep, isA<HostedDependency>());
      expect((dep! as HostedDependency).version.toString(), '^1.5.0');
    });

    test('uses provided constraint as-is', () async {
      final RepositoryPackage package =
          createFakePackage('a_package', packagesDir, examples: <String>[]);
      addDependency(package, 'target_package');

      const String providedConstraint = '>=1.6.0 <3.0.0';
      await runCapturingPrint(runner, <String>[
        'update-dependency',
        '--pub-package',
        'target_package',
        '--version',
        providedConstraint
      ]);

      final Dependency? dep =
          package.parsePubspec().dependencies['target_package'];
      expect(dep, isA<HostedDependency>());
      expect((dep! as HostedDependency).version.toString(), providedConstraint);
    });

    test('uses provided version as lower bound for unpinned', () async {
      final RepositoryPackage package =
          createFakePackage('a_package', packagesDir, examples: <String>[]);
      addDependency(package, 'target_package');

      await runCapturingPrint(runner, <String>[
        'update-dependency',
        '--pub-package',
        'target_package',
        '--version',
        '1.5.0'
      ]);

      final Dependency? dep =
          package.parsePubspec().dependencies['target_package'];
      expect(dep, isA<HostedDependency>());
      expect((dep! as HostedDependency).version.toString(), '^1.5.0');
    });

    test('uses provided version as exact version for pinned', () async {
      final RepositoryPackage package =
          createFakePackage('a_package', packagesDir, examples: <String>[]);
      addDependency(package, 'target_package', version: '1.0.0');

      await runCapturingPrint(runner, <String>[
        'update-dependency',
        '--pub-package',
        'target_package',
        '--version',
        '1.5.0'
      ]);

      final Dependency? dep =
          package.parsePubspec().dependencies['target_package'];
      expect(dep, isA<HostedDependency>());
      expect((dep! as HostedDependency).version.toString(), '1.5.0');
    });

    test('uses latest pub version as lower bound for unpinned', () async {
      final RepositoryPackage package =
          createFakePackage('a_package', packagesDir, examples: <String>[]);
      addDependency(package, 'target_package');

      const Map<String, dynamic> targetPackagePubResponse = <String, dynamic>{
        'name': 'a',
        'versions': <String>[
          '0.0.1',
          '1.0.0',
          '1.5.0',
        ],
      };
      mockHttpResponse = (http.Request request) async {
        if (request.url.pathSegments.last == 'target_package.json') {
          return http.Response(json.encode(targetPackagePubResponse), 200);
        }
        return http.Response('', 500);
      };

      await runCapturingPrint(runner, <String>[
        'update-dependency',
        '--pub-package',
        'target_package',
      ]);

      final Dependency? dep =
          package.parsePubspec().dependencies['target_package'];
      expect(dep, isA<HostedDependency>());
      expect((dep! as HostedDependency).version.toString(), '^1.5.0');
    });

    test('uses latest pub version as exact version for pinned', () async {
      final RepositoryPackage package =
          createFakePackage('a_package', packagesDir, examples: <String>[]);
      addDependency(package, 'target_package', version: '1.0.0');

      const Map<String, dynamic> targetPackagePubResponse = <String, dynamic>{
        'name': 'a',
        'versions': <String>[
          '0.0.1',
          '1.0.0',
          '1.5.0',
        ],
      };
      mockHttpResponse = (http.Request request) async {
        if (request.url.pathSegments.last == 'target_package.json') {
          return http.Response(json.encode(targetPackagePubResponse), 200);
        }
        return http.Response('', 500);
      };

      await runCapturingPrint(runner, <String>[
        'update-dependency',
        '--pub-package',
        'target_package',
      ]);

      final Dependency? dep =
          package.parsePubspec().dependencies['target_package'];
      expect(dep, isA<HostedDependency>());
      expect((dep! as HostedDependency).version.toString(), '1.5.0');
    });

    test('regenerates all pigeon files when updating pigeon', () async {
      final RepositoryPackage package =
          createFakePackage('a_package', packagesDir, extraFiles: <String>[
        'pigeons/foo.dart',
        'pigeons/bar.dart',
      ]);
      addDependency(package, 'pigeon', version: '1.0.0');

      await runCapturingPrint(runner, <String>[
        'update-dependency',
        '--pub-package',
        'pigeon',
        '--version',
        '1.5.0',
      ]);

      expect(
        processRunner.recordedCalls,
        orderedEquals(<ProcessCall>[
          ProcessCall(
            'dart',
            const <String>['pub', 'get'],
            package.path,
          ),
          ProcessCall(
            'dart',
            const <String>['run', 'pigeon', '--input', 'pigeons/foo.dart'],
            package.path,
          ),
          ProcessCall(
            'dart',
            const <String>['run', 'pigeon', '--input', 'pigeons/bar.dart'],
            package.path,
          ),
        ]),
      );
    });

    test('warns when regenerating pigeon if there are no pigeon files',
        () async {
      final RepositoryPackage package =
          createFakePackage('a_package', packagesDir);
      addDependency(package, 'pigeon', version: '1.0.0');

      final List<String> output = await runCapturingPrint(runner, <String>[
        'update-dependency',
        '--pub-package',
        'pigeon',
        '--version',
        '1.5.0',
      ]);

      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('No pigeon input files found'),
        ]),
      );
    });

    test('updating pigeon fails if pub get fails', () async {
      final RepositoryPackage package = createFakePackage(
          'a_package', packagesDir,
          extraFiles: <String>['pigeons/foo.dart']);
      addDependency(package, 'pigeon', version: '1.0.0');

      processRunner.mockProcessesForExecutable['dart'] = <FakeProcessInfo>[
        FakeProcessInfo(MockProcess(exitCode: 1), <String>['pub', 'get'])
      ];

      Error? commandError;
      final List<String> output = await runCapturingPrint(runner, <String>[
        'update-dependency',
        '--pub-package',
        'pigeon',
        '--version',
        '1.5.0',
      ], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Fetching dependencies failed'),
          contains('Failed to update pigeon files'),
        ]),
      );
    });

    test('updating pigeon fails if running pigeon fails', () async {
      final RepositoryPackage package = createFakePackage(
          'a_package', packagesDir,
          extraFiles: <String>['pigeons/foo.dart']);
      addDependency(package, 'pigeon', version: '1.0.0');

      processRunner.mockProcessesForExecutable['dart'] = <FakeProcessInfo>[
        FakeProcessInfo(MockProcess(), <String>['pub', 'get']),
        FakeProcessInfo(MockProcess(exitCode: 1), <String>['run', 'pigeon']),
      ];

      Error? commandError;
      final List<String> output = await runCapturingPrint(runner, <String>[
        'update-dependency',
        '--pub-package',
        'pigeon',
        '--version',
        '1.5.0',
      ], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('dart run pigeon failed'),
          contains('Failed to update pigeon files'),
        ]),
      );
    });

    test('regenerates mocks when updating mockito if necessary', () async {
      final RepositoryPackage package =
          createFakePackage('a_package', packagesDir);
      addDependency(package, 'mockito', version: '1.0.0');
      addDevDependency(package, 'build_runner');

      await runCapturingPrint(runner, <String>[
        'update-dependency',
        '--pub-package',
        'mockito',
        '--version',
        '1.5.0',
      ]);

      expect(
        processRunner.recordedCalls,
        orderedEquals(<ProcessCall>[
          ProcessCall(
            'dart',
            const <String>['pub', 'get'],
            package.path,
          ),
          ProcessCall(
            'dart',
            const <String>[
              'run',
              'build_runner',
              'build',
              '--delete-conflicting-outputs'
            ],
            package.path,
          ),
        ]),
      );
    });

    test('skips regenerating mocks when there is no build_runner dependency',
        () async {
      final RepositoryPackage package =
          createFakePackage('a_package', packagesDir);
      addDependency(package, 'mockito', version: '1.0.0');

      await runCapturingPrint(runner, <String>[
        'update-dependency',
        '--pub-package',
        'mockito',
        '--version',
        '1.5.0',
      ]);

      expect(processRunner.recordedCalls.isEmpty, true);
    });

    test('updating mockito fails if pub get fails', () async {
      final RepositoryPackage package =
          createFakePackage('a_package', packagesDir);
      addDependency(package, 'mockito', version: '1.0.0');
      addDevDependency(package, 'build_runner');

      processRunner.mockProcessesForExecutable['dart'] = <FakeProcessInfo>[
        FakeProcessInfo(MockProcess(exitCode: 1), <String>['pub', 'get'])
      ];

      Error? commandError;
      final List<String> output = await runCapturingPrint(runner, <String>[
        'update-dependency',
        '--pub-package',
        'mockito',
        '--version',
        '1.5.0',
      ], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Fetching dependencies failed'),
          contains('Failed to update mocks'),
        ]),
      );
    });

    test('updating mockito fails if running build_runner fails', () async {
      final RepositoryPackage package =
          createFakePackage('a_package', packagesDir);
      addDependency(package, 'mockito', version: '1.0.0');
      addDevDependency(package, 'build_runner');

      processRunner.mockProcessesForExecutable['dart'] = <FakeProcessInfo>[
        FakeProcessInfo(MockProcess(), <String>['pub', 'get']),
        FakeProcessInfo(
            MockProcess(exitCode: 1), <String>['run', 'build_runner']),
      ];

      Error? commandError;
      final List<String> output = await runCapturingPrint(runner, <String>[
        'update-dependency',
        '--pub-package',
        'mockito',
        '--version',
        '1.5.0',
      ], errorHandler: (Error e) {
        commandError = e;
      });

      expect(commandError, isA<ToolExit>());
      expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('"dart run build_runner build" failed'),
          contains('Failed to update mocks'),
        ]),
      );
    });
  });

  group('Android dependencies', () {
    group('gradle', () {
      test('throws if version format is invalid', () async {
        Error? commandError;
        final List<String> output = await runCapturingPrint(runner, <String>[
          'update-dependency',
          '--android-dependency',
          'gradle',
          '--version',
          '83',
        ], errorHandler: (Error e) {
          commandError = e;
        });

        expect(commandError, isA<ToolExit>());
        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains(
                'A version with a valid format (maximum 2-3 numbers separated by period) must be provided.'),
          ]),
        );
      });

      test('skips if example app does not run on Android', () async {
        final RepositoryPackage package =
            createFakePlugin('fake_plugin', packagesDir);

        final List<String> output = await runCapturingPrint(runner, <String>[
          'update-dependency',
          '--packages',
          package.displayName,
          '--android-dependency',
          'gradle',
          '--version',
          '8.8.8',
        ]);

        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains('SKIPPING: No example apps run on Android.'),
          ]),
        );
      });

      test(
          'throws if wrapper does not have distribution URL with expected format',
          () async {
        final RepositoryPackage package = createFakePlugin(
            'fake_plugin', packagesDir, extraFiles: <String>[
          'example/android/app/gradle/wrapper/gradle-wrapper.properties'
        ]);

        final File gradleWrapperPropertiesFile = package.directory
            .childDirectory('example')
            .childDirectory('android')
            .childDirectory('app')
            .childDirectory('gradle')
            .childDirectory('wrapper')
            .childFile('gradle-wrapper.properties');

        gradleWrapperPropertiesFile.writeAsStringSync('''
How is it even possible that I didn't specify a Gradle distribution?
''');

        Error? commandError;
        final List<String> output = await runCapturingPrint(runner, <String>[
          'update-dependency',
          '--packages',
          package.displayName,
          '--android-dependency',
          'gradle',
          '--version',
          '8.8.8',
        ], errorHandler: (Error e) {
          commandError = e;
        });

        expect(commandError, isA<ToolExit>());
        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains(
                'Unable to find a gradle version entry to update for ${package.displayName}/example.'),
          ]),
        );
      });

      test('succeeds if example app has android/app/gradle directory structure',
          () async {
        final RepositoryPackage package = createFakePlugin(
            'fake_plugin', packagesDir, extraFiles: <String>[
          'example/android/app/gradle/wrapper/gradle-wrapper.properties'
        ]);
        const String newGradleVersion = '8.8.8';

        final File gradleWrapperPropertiesFile = package.directory
            .childDirectory('example')
            .childDirectory('android')
            .childDirectory('app')
            .childDirectory('gradle')
            .childDirectory('wrapper')
            .childFile('gradle-wrapper.properties');

        gradleWrapperPropertiesFile.writeAsStringSync(r'''
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
''');

        await runCapturingPrint(runner, <String>[
          'update-dependency',
          '--packages',
          package.displayName,
          '--android-dependency',
          'gradle',
          '--version',
          newGradleVersion,
        ]);

        final String updatedGradleWrapperPropertiesContents =
            gradleWrapperPropertiesFile.readAsStringSync();
        expect(
            updatedGradleWrapperPropertiesContents,
            contains(
                r'distributionUrl=https\://services.gradle.org/distributions/'
                'gradle-$newGradleVersion-all.zip'));
      });

      test('succeeds if example app has android/gradle directory structure',
          () async {
        final RepositoryPackage package = createFakePlugin(
            'fake_plugin', packagesDir, extraFiles: <String>[
          'example/android/gradle/wrapper/gradle-wrapper.properties'
        ]);
        const String newGradleVersion = '9.9';

        final File gradleWrapperPropertiesFile = package.directory
            .childDirectory('example')
            .childDirectory('android')
            .childDirectory('gradle')
            .childDirectory('wrapper')
            .childFile('gradle-wrapper.properties');

        gradleWrapperPropertiesFile.writeAsStringSync(r'''
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
''');

        await runCapturingPrint(runner, <String>[
          'update-dependency',
          '--packages',
          package.displayName,
          '--android-dependency',
          'gradle',
          '--version',
          newGradleVersion,
        ]);

        final String updatedGradleWrapperPropertiesContents =
            gradleWrapperPropertiesFile.readAsStringSync();
        expect(
            updatedGradleWrapperPropertiesContents,
            contains(
                r'distributionUrl=https\://services.gradle.org/distributions/'
                'gradle-$newGradleVersion-all.zip'));
      });

      test(
          'succeeds if example app has android/gradle and android/app/gradle directory structure',
          () async {
        final RepositoryPackage package =
            createFakePlugin('fake_plugin', packagesDir, extraFiles: <String>[
          'example/android/gradle/wrapper/gradle-wrapper.properties',
          'example/android/app/gradle/wrapper/gradle-wrapper.properties'
        ]);
        const String newGradleVersion = '9.9';

        final File gradleWrapperPropertiesFile = package.directory
            .childDirectory('example')
            .childDirectory('android')
            .childDirectory('gradle')
            .childDirectory('wrapper')
            .childFile('gradle-wrapper.properties');

        final File gradleAppWrapperPropertiesFile = package.directory
            .childDirectory('example')
            .childDirectory('android')
            .childDirectory('app')
            .childDirectory('gradle')
            .childDirectory('wrapper')
            .childFile('gradle-wrapper.properties');

        gradleWrapperPropertiesFile.writeAsStringSync(r'''
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
''');

        gradleAppWrapperPropertiesFile.writeAsStringSync(r'''
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
''');

        await runCapturingPrint(runner, <String>[
          'update-dependency',
          '--packages',
          package.displayName,
          '--android-dependency',
          'gradle',
          '--version',
          newGradleVersion,
        ]);

        final String updatedGradleWrapperPropertiesContents =
            gradleWrapperPropertiesFile.readAsStringSync();
        final String updatedGradleAppWrapperPropertiesContents =
            gradleAppWrapperPropertiesFile.readAsStringSync();
        expect(
            updatedGradleWrapperPropertiesContents,
            contains(
                r'distributionUrl=https\://services.gradle.org/distributions/'
                'gradle-$newGradleVersion-all.zip'));
        expect(
            updatedGradleAppWrapperPropertiesContents,
            contains(
                r'distributionUrl=https\://services.gradle.org/distributions/'
                'gradle-$newGradleVersion-all.zip'));
      });

      test('succeeds if one example app runs on Android and another does not',
          () async {
        final RepositoryPackage package = createFakePlugin(
            'fake_plugin', packagesDir, examples: <String>[
          'example_1',
          'example_2'
        ], extraFiles: <String>[
          'example/example_2/android/app/gradle/wrapper/gradle-wrapper.properties'
        ]);
        const String newGradleVersion = '8.8.8';

        final File gradleWrapperPropertiesFile = package.directory
            .childDirectory('example')
            .childDirectory('example_2')
            .childDirectory('android')
            .childDirectory('app')
            .childDirectory('gradle')
            .childDirectory('wrapper')
            .childFile('gradle-wrapper.properties');

        gradleWrapperPropertiesFile.writeAsStringSync(r'''
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
''');

        await runCapturingPrint(runner, <String>[
          'update-dependency',
          '--packages',
          package.displayName,
          '--android-dependency',
          'gradle',
          '--version',
          newGradleVersion,
        ]);

        final String updatedGradleWrapperPropertiesContents =
            gradleWrapperPropertiesFile.readAsStringSync();
        expect(
            updatedGradleWrapperPropertiesContents,
            contains(
                r'distributionUrl=https\://services.gradle.org/distributions/'
                'gradle-$newGradleVersion-all.zip'));
      });
    });

    group('compileSdk/compileSdkForExamples', () {
      // Tests if the compileSdk version is updated for the provided
      // build.gradle file and new compileSdk version to update to.
      Future<void> testCompileSdkVersionUpdated(
          {required RepositoryPackage package,
          required File buildGradleFile,
          required String oldCompileSdkVersion,
          required String newCompileSdkVersion,
          bool runForExamples = false,
          bool checkForDeprecatedCompileSdkVersion = false}) async {
        buildGradleFile.writeAsStringSync('''
android {
    // Conditional for compatibility with AGP <4.2.
    if (project.android.hasProperty("namespace")) {
        namespace 'io.flutter.plugins.pathprovider'
    }
    ${checkForDeprecatedCompileSdkVersion ? 'compileSdkVersion' : 'compileSdk'} $oldCompileSdkVersion
''');

        await runCapturingPrint(runner, <String>[
          'update-dependency',
          '--packages',
          package.displayName,
          '--android-dependency',
          if (runForExamples) 'compileSdkForExamples' else 'compileSdk',
          '--version',
          newCompileSdkVersion,
        ]);

        final String updatedBuildGradleContents =
            buildGradleFile.readAsStringSync();
        // compileSdkVersion is now deprecated, so if the tool finds any
        // instances of compileSdk OR compileSdkVersion, it should change it
        // to compileSdk. See https://developer.android.com/reference/tools/gradle-api/7.2/com/android/build/api/dsl/CommonExtension#compileSdkVersion(kotlin.Int).
        expect(updatedBuildGradleContents,
            contains('compileSdk $newCompileSdkVersion'));
      }

      test('throws if version format is invalid for compileSdk', () async {
        Error? commandError;
        final List<String> output = await runCapturingPrint(runner, <String>[
          'update-dependency',
          '--android-dependency',
          'compileSdk',
          '--version',
          '834',
        ], errorHandler: (Error e) {
          commandError = e;
        });

        expect(commandError, isA<ToolExit>());
        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains(
                'A valid Android SDK version number (1-2 digit numbers) must be provided.'),
          ]),
        );
      });

      test('throws if version format is invalid for compileSdkForExamples',
          () async {
        Error? commandError;
        final List<String> output = await runCapturingPrint(runner, <String>[
          'update-dependency',
          '--android-dependency',
          'compileSdkForExamples',
          '--version',
          '438',
        ], errorHandler: (Error e) {
          commandError = e;
        });

        expect(commandError, isA<ToolExit>());
        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains(
                'A valid Android SDK version number (1-2 digit numbers) must be provided.'),
          ]),
        );
      });

      test('skips if plugin does not run on Android', () async {
        final RepositoryPackage package =
            createFakePlugin('fake_plugin', packagesDir);

        final List<String> output = await runCapturingPrint(runner, <String>[
          'update-dependency',
          '--packages',
          package.displayName,
          '--android-dependency',
          'compileSdk',
          '--version',
          '34',
        ]);

        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains(
                'SKIPPING: Package ${package.displayName} does not run on Android.'),
          ]),
        );
      });

      test('skips if plugin example does not run on Android', () async {
        final RepositoryPackage package =
            createFakePlugin('fake_plugin', packagesDir);

        final List<String> output = await runCapturingPrint(runner, <String>[
          'update-dependency',
          '--packages',
          package.displayName,
          '--android-dependency',
          'compileSdkForExamples',
          '--version',
          '34',
        ]);

        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains('SKIPPING: No example apps run on Android.'),
          ]),
        );
      });

      test(
          'throws if build configuration file does not have compileSdk version with expected format for compileSdk',
          () async {
        final RepositoryPackage package = createFakePlugin(
            'fake_plugin', packagesDir,
            extraFiles: <String>['android/build.gradle']);

        final File buildGradleFile = package.directory
            .childDirectory('android')
            .childFile('build.gradle');

        buildGradleFile.writeAsStringSync('''
How is it even possible that I didn't specify a compileSdk version?
''');

        Error? commandError;
        final List<String> output = await runCapturingPrint(runner, <String>[
          'update-dependency',
          '--packages',
          package.displayName,
          '--android-dependency',
          'compileSdk',
          '--version',
          '34',
        ], errorHandler: (Error e) {
          commandError = e;
        });

        expect(commandError, isA<ToolExit>());
        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains(
                'Unable to find a compileSdk version entry to update for ${package.displayName}.'),
          ]),
        );
      });

      test(
          'throws if build configuration file does not have compileSdk version with expected format for compileSdkForExamples',
          () async {
        final RepositoryPackage package = createFakePlugin(
            'fake_plugin', packagesDir,
            extraFiles: <String>['example/android/app/build.gradle']);

        final File buildGradleFile = package.directory
            .childDirectory('example')
            .childDirectory('android')
            .childDirectory('app')
            .childFile('build.gradle');

        buildGradleFile.writeAsStringSync('''
How is it even possible that I didn't specify a compileSdk version?
''');

        Error? commandError;
        final List<String> output = await runCapturingPrint(runner, <String>[
          'update-dependency',
          '--packages',
          package.displayName,
          '--android-dependency',
          'compileSdkForExamples',
          '--version',
          '34',
        ], errorHandler: (Error e) {
          commandError = e;
        });

        expect(commandError, isA<ToolExit>());
        expect(
          output,
          containsAllInOrder(<Matcher>[
            contains(
                'Unable to find a compileSdkForExamples version entry to update for ${package.displayName}/example.'),
          ]),
        );
      });

      test(
          'succeeds if plugin runs on Android and valid version is supplied for compileSdkVersion entry',
          () async {
        final RepositoryPackage package = createFakePlugin(
            'fake_plugin', packagesDir, extraFiles: <String>[
          'android/build.gradle',
          'example/android/app/build.gradle'
        ]);
        final File buildGradleFile = package.directory
            .childDirectory('android')
            .childFile('build.gradle');

        await testCompileSdkVersionUpdated(
            package: package,
            buildGradleFile: buildGradleFile,
            oldCompileSdkVersion: '8',
            newCompileSdkVersion: '16',
            checkForDeprecatedCompileSdkVersion: true);
      });

      test(
          'succeeds if plugin example runs on Android and valid version is supplied for compileSdkVersion entry',
          () async {
        final RepositoryPackage package = createFakePlugin(
            'fake_plugin', packagesDir, extraFiles: <String>[
          'android/build.gradle',
          'example/android/app/build.gradle'
        ]);
        final File exampleBuildGradleFile = package.directory
            .childDirectory('example')
            .childDirectory('android')
            .childDirectory('app')
            .childFile('build.gradle');

        await testCompileSdkVersionUpdated(
            package: package,
            buildGradleFile: exampleBuildGradleFile,
            oldCompileSdkVersion: '8',
            newCompileSdkVersion: '16',
            runForExamples: true,
            checkForDeprecatedCompileSdkVersion: true);
      });

      test(
          'succeeds if plugin runs on Android and valid version is supplied for compileSdk entry',
          () async {
        final RepositoryPackage package = createFakePlugin(
            'fake_plugin', packagesDir, extraFiles: <String>[
          'android/build.gradle',
          'example/android/app/build.gradle'
        ]);

        final File buildGradleFile = package.directory
            .childDirectory('android')
            .childFile('build.gradle');
        await testCompileSdkVersionUpdated(
            package: package,
            buildGradleFile: buildGradleFile,
            oldCompileSdkVersion: '8',
            newCompileSdkVersion: '16');
      });

      test(
          'succeeds if plugin example runs on Android and valid version is supplied for compileSdk entry',
          () async {
        final RepositoryPackage package = createFakePlugin(
            'fake_plugin', packagesDir, extraFiles: <String>[
          'android/build.gradle',
          'example/android/app/build.gradle'
        ]);

        final File exampleBuildGradleFile = package.directory
            .childDirectory('example')
            .childDirectory('android')
            .childDirectory('app')
            .childFile('build.gradle');
        await testCompileSdkVersionUpdated(
            package: package,
            buildGradleFile: exampleBuildGradleFile,
            oldCompileSdkVersion: '33',
            newCompileSdkVersion: '34',
            runForExamples: true);
      });
    });
  });
}
