// Copyright 2013 The Flutter Authors
// 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:flutter_plugin_tools/src/common/core.dart';
import 'package:flutter_plugin_tools/src/fix_command.dart';
import 'package:git/git.dart';
import 'package:test/test.dart';

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

void main() {
  late MockPlatform mockPlatform;
  late Directory packagesDir;
  late RecordingProcessRunner processRunner;
  late CommandRunner<void> runner;

  setUp(() {
    mockPlatform = MockPlatform();
    final GitDir gitDir;
    (:packagesDir, :processRunner, gitProcessRunner: _, :gitDir) =
        configureBaseCommandMocks(platform: mockPlatform);
    final command = FixCommand(
      packagesDir,
      processRunner: processRunner,
      platform: mockPlatform,
      gitDir: gitDir,
    );

    runner = CommandRunner<void>('fix_command', 'Test for fix_command');
    runner.addCommand(command);
  });

  test('runs fix in top-level packages and subpackages', () async {
    final RepositoryPackage package = createFakePackage('a', packagesDir);
    final RepositoryPackage plugin = createFakePlugin('b', packagesDir);

    await runCapturingPrint(runner, <String>['fix']);

    expect(
      processRunner.recordedCalls,
      orderedEquals(<ProcessCall>[
        ProcessCall('dart', const <String>['fix', '--apply'], package.path),
        ProcessCall('dart', const <String>[
          'fix',
          '--apply',
        ], package.getExamples().first.path),
        ProcessCall('dart', const <String>['fix', '--apply'], plugin.path),
        ProcessCall('dart', const <String>[
          'fix',
          '--apply',
        ], plugin.getExamples().first.path),
      ]),
    );
  });

  test('fails if "dart fix" fails', () async {
    createFakePlugin('foo', packagesDir);

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

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

    expect(commandError, isA<ToolExit>());
    expect(
      output,
      containsAllInOrder(<Matcher>[
        contains('Unable to automatically fix package.'),
      ]),
    );
  });
}
