// 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: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/dependabot_check_command.dart';
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';

import 'common/package_command_test.mocks.dart';
import 'util.dart';

void main() {
  late CommandRunner<void> runner;
  late FileSystem fileSystem;
  late Directory root;
  late Directory packagesDir;

  setUp(() {
    fileSystem = MemoryFileSystem();
    root = fileSystem.currentDirectory;
    packagesDir = root.childDirectory('packages');

    final MockGitDir gitDir = MockGitDir();
    when(gitDir.path).thenReturn(root.path);

    final DependabotCheckCommand command = DependabotCheckCommand(
      packagesDir,
      gitDir: gitDir,
    );
    runner = CommandRunner<void>(
        'dependabot_test', 'Test for $DependabotCheckCommand');
    runner.addCommand(command);
  });

  void setDependabotCoverage({
    Iterable<String> gradleDirs = const <String>[],
  }) {
    final Iterable<String> gradleEntries =
        gradleDirs.map((String directory) => '''
  - package-ecosystem: "gradle"
    directory: "/$directory"
    schedule:
      interval: "daily"
''');
    final File configFile =
        root.childDirectory('.github').childFile('dependabot.yml');
    configFile.createSync(recursive: true);
    configFile.writeAsStringSync('''
version: 2
updates:
${gradleEntries.join('\n')}
''');
  }

  test('skips with no supported ecosystems', () async {
    setDependabotCoverage();
    createFakePackage('a_package', packagesDir);

    final List<String> output =
        await runCapturingPrint(runner, <String>['dependabot-check']);

    expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('SKIPPING: No supported package ecosystems'),
        ]));
  });

  test('fails for app missing Gradle coverage', () async {
    setDependabotCoverage();
    final RepositoryPackage package =
        createFakePackage('a_package', packagesDir);
    package.directory
        .childDirectory('example')
        .childDirectory('android')
        .childDirectory('app')
        .createSync(recursive: true);

    Error? commandError;
    final List<String> output = await runCapturingPrint(
        runner, <String>['dependabot-check'], errorHandler: (Error e) {
      commandError = e;
    });

    expect(commandError, isA<ToolExit>());
    expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Missing Gradle coverage.'),
          contains(
              'Add a "gradle" entry to .github/dependabot.yml for /packages/a_package/example/android/app'),
          contains('a_package/example:\n'
              '    Missing Gradle coverage')
        ]));
  });

  test('fails for plugin missing Gradle coverage', () async {
    setDependabotCoverage();
    final RepositoryPackage plugin = createFakePlugin('a_plugin', packagesDir);
    plugin.directory.childDirectory('android').createSync(recursive: true);

    Error? commandError;
    final List<String> output = await runCapturingPrint(
        runner, <String>['dependabot-check'], errorHandler: (Error e) {
      commandError = e;
    });

    expect(commandError, isA<ToolExit>());
    expect(
        output,
        containsAllInOrder(<Matcher>[
          contains('Missing Gradle coverage.'),
          contains(
              'Add a "gradle" entry to .github/dependabot.yml for /packages/a_plugin/android'),
          contains('a_plugin:\n'
              '    Missing Gradle coverage')
        ]));
  });

  test('passes for correct Gradle coverage', () async {
    setDependabotCoverage(gradleDirs: <String>[
      'packages/a_plugin/android',
      'packages/a_plugin/example/android/app',
    ]);
    final RepositoryPackage plugin = createFakePlugin('a_plugin', packagesDir);
    // Test the plugin.
    plugin.directory.childDirectory('android').createSync(recursive: true);
    // And its example app.
    plugin.directory
        .childDirectory('example')
        .childDirectory('android')
        .childDirectory('app')
        .createSync(recursive: true);

    final List<String> output =
        await runCapturingPrint(runner, <String>['dependabot-check']);

    expect(output,
        containsAllInOrder(<Matcher>[contains('Ran for 2 package(s)')]));
  });
}
