// 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 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_plugin_tools/src/common/git_version_finder.dart';
import 'package:flutter_plugin_tools/src/common/package_state_utils.dart';
import 'package:test/fake.dart';
import 'package:test/test.dart';

import '../util.dart';

void main() {
  late FileSystem fileSystem;
  late Directory packagesDir;

  setUp(() {
    fileSystem = MemoryFileSystem();
    packagesDir = createPackagesDirectory(fileSystem: fileSystem);
  });

  group('checkPackageChangeState', () {
    test('reports version change needed for code changes', () async {
      final RepositoryPackage package =
          createFakePackage('a_package', packagesDir);

      const List<String> changedFiles = <String>[
        'packages/a_package/lib/plugin.dart',
      ];

      final PackageChangeState state = await checkPackageChangeState(package,
          changedPaths: changedFiles,
          relativePackagePath: 'packages/a_package');

      expect(state.hasChanges, true);
      expect(state.needsVersionChange, true);
      expect(state.needsChangelogChange, true);
    });

    test('handles trailing slash on package path', () async {
      final RepositoryPackage package =
          createFakePackage('a_package', packagesDir);

      const List<String> changedFiles = <String>[
        'packages/a_package/lib/plugin.dart',
      ];

      final PackageChangeState state = await checkPackageChangeState(package,
          changedPaths: changedFiles,
          relativePackagePath: 'packages/a_package/');

      expect(state.hasChanges, true);
      expect(state.needsVersionChange, true);
      expect(state.needsChangelogChange, true);
      expect(state.hasChangelogChange, false);
    });

    test('does not flag version- and changelog-change-exempt changes',
        () async {
      final RepositoryPackage package =
          createFakePlugin('a_plugin', packagesDir);

      const List<String> changedFiles = <String>[
        'packages/a_plugin/CHANGELOG.md',
        // Analysis.
        'packages/a_plugin/example/android/lint-baseline.xml',
        // Tests.
        'packages/a_plugin/example/android/src/androidTest/foo/bar/FooTest.java',
        'packages/a_plugin/example/ios/RunnerTests/Foo.m',
        'packages/a_plugin/example/ios/RunnerUITests/info.plist',
        // Test scripts.
        'packages/a_plugin/run_tests.sh',
        // Tools.
        'packages/a_plugin/tool/a_development_tool.dart',
        // Example build files.
        'packages/a_plugin/example/android/build.gradle',
        'packages/a_plugin/example/android/gradle/wrapper/gradle-wrapper.properties',
        'packages/a_plugin/example/ios/Runner.xcodeproj/project.pbxproj',
        'packages/a_plugin/example/linux/flutter/CMakeLists.txt',
        'packages/a_plugin/example/macos/Runner.xcodeproj/project.pbxproj',
        'packages/a_plugin/example/windows/CMakeLists.txt',
        'packages/a_plugin/example/pubspec.yaml',
        // Pigeon platform tests, which have an unusual structure.
        'packages/a_plugin/platform_tests/shared_test_plugin_code/lib/integration_tests.dart',
        'packages/a_plugin/platform_tests/test_plugin/windows/test_plugin.cpp',
      ];

      final PackageChangeState state = await checkPackageChangeState(package,
          changedPaths: changedFiles,
          relativePackagePath: 'packages/a_plugin/');

      expect(state.hasChanges, true);
      expect(state.needsVersionChange, false);
      expect(state.needsChangelogChange, false);
      expect(state.hasChangelogChange, true);
    });

    test('only considers a root "tool" folder to be special', () async {
      final RepositoryPackage package =
          createFakePlugin('a_plugin', packagesDir);

      const List<String> changedFiles = <String>[
        'packages/a_plugin/lib/foo/tool/tool_thing.dart',
      ];

      final PackageChangeState state = await checkPackageChangeState(package,
          changedPaths: changedFiles,
          relativePackagePath: 'packages/a_plugin/');

      expect(state.hasChanges, true);
      expect(state.needsVersionChange, true);
      expect(state.needsChangelogChange, true);
    });

    test('requires a version change for example/lib/main.dart', () async {
      final RepositoryPackage package = createFakePlugin(
          'a_plugin', packagesDir,
          extraFiles: <String>['example/lib/main.dart']);

      const List<String> changedFiles = <String>[
        'packages/a_plugin/example/lib/main.dart',
      ];

      final PackageChangeState state = await checkPackageChangeState(package,
          changedPaths: changedFiles,
          relativePackagePath: 'packages/a_plugin/');

      expect(state.hasChanges, true);
      expect(state.needsVersionChange, true);
      expect(state.needsChangelogChange, true);
    });

    test('requires a version change for example/main.dart', () async {
      final RepositoryPackage package = createFakePlugin(
          'a_plugin', packagesDir,
          extraFiles: <String>['example/main.dart']);

      const List<String> changedFiles = <String>[
        'packages/a_plugin/example/main.dart',
      ];

      final PackageChangeState state = await checkPackageChangeState(package,
          changedPaths: changedFiles,
          relativePackagePath: 'packages/a_plugin/');

      expect(state.hasChanges, true);
      expect(state.needsVersionChange, true);
      expect(state.needsChangelogChange, true);
    });

    test('requires a version change for example readme.md', () async {
      final RepositoryPackage package =
          createFakePlugin('a_plugin', packagesDir);

      const List<String> changedFiles = <String>[
        'packages/a_plugin/example/README.md',
      ];

      final PackageChangeState state = await checkPackageChangeState(package,
          changedPaths: changedFiles,
          relativePackagePath: 'packages/a_plugin/');

      expect(state.hasChanges, true);
      expect(state.needsVersionChange, true);
      expect(state.needsChangelogChange, true);
    });

    test('requires a version change for example/example.md', () async {
      final RepositoryPackage package = createFakePlugin(
          'a_plugin', packagesDir,
          extraFiles: <String>['example/example.md']);

      const List<String> changedFiles = <String>[
        'packages/a_plugin/example/example.md',
      ];

      final PackageChangeState state = await checkPackageChangeState(package,
          changedPaths: changedFiles,
          relativePackagePath: 'packages/a_plugin/');

      expect(state.hasChanges, true);
      expect(state.needsVersionChange, true);
      expect(state.needsChangelogChange, true);
    });

    test(
        'requires a changelog change but no version change for '
        'lower-priority examples when example.md is present', () async {
      final RepositoryPackage package = createFakePlugin(
          'a_plugin', packagesDir,
          extraFiles: <String>['example/example.md']);

      const List<String> changedFiles = <String>[
        'packages/a_plugin/example/lib/main.dart',
        'packages/a_plugin/example/main.dart',
        'packages/a_plugin/example/README.md',
      ];

      final PackageChangeState state = await checkPackageChangeState(package,
          changedPaths: changedFiles,
          relativePackagePath: 'packages/a_plugin/');

      expect(state.hasChanges, true);
      expect(state.needsVersionChange, false);
      expect(state.needsChangelogChange, true);
    });

    test(
        'requires a changelog change but no version change for README.md when '
        'code example is present', () async {
      final RepositoryPackage package = createFakePlugin(
          'a_plugin', packagesDir,
          extraFiles: <String>['example/lib/main.dart']);

      const List<String> changedFiles = <String>[
        'packages/a_plugin/example/README.md',
      ];

      final PackageChangeState state = await checkPackageChangeState(package,
          changedPaths: changedFiles,
          relativePackagePath: 'packages/a_plugin/');

      expect(state.hasChanges, true);
      expect(state.needsVersionChange, false);
      expect(state.needsChangelogChange, true);
    });

    test(
        'does not requires changelog or version change for build.gradle '
        'test-dependency-only changes', () async {
      final RepositoryPackage package =
          createFakePlugin('a_plugin', packagesDir);

      const List<String> changedFiles = <String>[
        'packages/a_plugin/android/build.gradle',
      ];

      final GitVersionFinder git = FakeGitVersionFinder(<String, List<String>>{
        'packages/a_plugin/android/build.gradle': <String>[
          "-  androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'",
          "-  testImplementation 'junit:junit:4.10.0'",
          "+  androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'",
          "+  testImplementation 'junit:junit:4.13.2'",
        ]
      });

      final PackageChangeState state = await checkPackageChangeState(package,
          changedPaths: changedFiles,
          relativePackagePath: 'packages/a_plugin/',
          git: git);

      expect(state.hasChanges, true);
      expect(state.needsVersionChange, false);
      expect(state.needsChangelogChange, false);
    });

    test('requires changelog or version change for other build.gradle changes',
        () async {
      final RepositoryPackage package =
          createFakePlugin('a_plugin', packagesDir);

      const List<String> changedFiles = <String>[
        'packages/a_plugin/android/build.gradle',
      ];

      final GitVersionFinder git = FakeGitVersionFinder(<String, List<String>>{
        'packages/a_plugin/android/build.gradle': <String>[
          "-  androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'",
          "-  testImplementation 'junit:junit:4.10.0'",
          "+  androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'",
          "+  testImplementation 'junit:junit:4.13.2'",
          "-  implementation 'com.google.android.gms:play-services-maps:18.0.0'",
          "+  implementation 'com.google.android.gms:play-services-maps:18.0.2'",
        ]
      });

      final PackageChangeState state = await checkPackageChangeState(package,
          changedPaths: changedFiles,
          relativePackagePath: 'packages/a_plugin/',
          git: git);

      expect(state.hasChanges, true);
      expect(state.needsVersionChange, true);
      expect(state.needsChangelogChange, true);
    });

    test(
        'requires changelog or version change if build.gradle diffs cannot '
        'be checked', () async {
      final RepositoryPackage package =
          createFakePlugin('a_plugin', packagesDir);

      const List<String> changedFiles = <String>[
        'packages/a_plugin/android/build.gradle',
      ];

      final PackageChangeState state = await checkPackageChangeState(package,
          changedPaths: changedFiles,
          relativePackagePath: 'packages/a_plugin/');

      expect(state.hasChanges, true);
      expect(state.needsVersionChange, true);
      expect(state.needsChangelogChange, true);
    });

    test(
        'requires changelog or version change if build.gradle diffs cannot '
        'be determined', () async {
      final RepositoryPackage package =
          createFakePlugin('a_plugin', packagesDir);

      const List<String> changedFiles = <String>[
        'packages/a_plugin/android/build.gradle',
      ];

      final GitVersionFinder git = FakeGitVersionFinder(<String, List<String>>{
        'packages/a_plugin/android/build.gradle': <String>[]
      });

      final PackageChangeState state = await checkPackageChangeState(package,
          changedPaths: changedFiles,
          relativePackagePath: 'packages/a_plugin/',
          git: git);

      expect(state.hasChanges, true);
      expect(state.needsVersionChange, true);
      expect(state.needsChangelogChange, true);
    });
  });
}

class FakeGitVersionFinder extends Fake implements GitVersionFinder {
  FakeGitVersionFinder(this.fileDiffs);

  final Map<String, List<String>> fileDiffs;

  @override
  Future<List<String>> getDiffContents({
    String? targetPath,
    bool includeUncommitted = false,
  }) async {
    return fileDiffs[targetPath]!;
  }
}
