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

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

void runAllTests(MockPlatform platform) {
  late FileSystem fileSystem;
  late Directory packagesDir;
  late CommandRunner<void> runner;

  setUp(() {
    fileSystem = MemoryFileSystem(
        style: platform.isWindows
            ? FileSystemStyle.windows
            : FileSystemStyle.posix);
    packagesDir = createPackagesDirectory(fileSystem: fileSystem);
    runner = CommandRunner<void>('', '')
      ..addCommand(UpdateExcerptsCommand(
        packagesDir,
        platform: platform,
        processRunner: RecordingProcessRunner(),
        gitDir: MockGitDir(),
      ));
  });

  Future<void> testInjection(
      {required String before,
      required String source,
      required String after,
      required String filename,
      bool failOnChange = false}) async {
    final RepositoryPackage package =
        createFakePackage('a_package', packagesDir);
    package.readmeFile.writeAsStringSync(before);
    package.directory.childFile(filename).writeAsStringSync(source);
    Object? errorObject;
    final List<String> output = await runCapturingPrint(
      runner,
      <String>[
        'update-excerpts',
        if (failOnChange) '--fail-on-change',
      ],
      errorHandler: (Object error) {
        errorObject = error;
      },
    );
    if (errorObject != null) {
      fail('Failed: $errorObject\n\nOutput from excerpt command:\n$output');
    }
    expect(package.readmeFile.readAsStringSync(), after);
  }

  test('succeeds when nothing has changed', () async {
    const String filename = 'main.dart';

    const String readme = '''
Example:

<?code-excerpt "$filename (SomeSection)"?>
```dart
A B C
```
''';
    const String source = '''
FAIL
// #docregion SomeSection
A B C
// #enddocregion SomeSection
FAIL
''';
    await testInjection(
        before: readme, source: source, after: readme, filename: filename);
  });

  test('fails if example injection fails', () async {
    final RepositoryPackage package =
        createFakePackage('a_package', packagesDir);
    package.readmeFile.writeAsStringSync('''
Example:

<?code-excerpt "main.dart (UnknownSection)"?>
```dart
A B C
```
''');
    package.directory.childFile('main.dart').writeAsStringSync('''
FAIL
// #docregion SomeSection
A B C
// #enddocregion SomeSection
FAIL
''');

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

    expect(commandError, isA<ToolExit>());
    expect(
      output,
      containsAllInOrder(<Matcher>[
        contains('Injecting excerpts failed:'),
        contains(
            'main.dart: did not find a "// #docregion UnknownSection" pragma'),
      ]),
    );
  });

  test('updates files', () async {
    const String filename = 'main.dart';

    const String before = '''
Example:

<?code-excerpt "$filename (SomeSection)"?>
```dart
X Y Z
```
''';

    const String source = '''
FAIL
// #docregion SomeSection
A B C
// #enddocregion SomeSection
FAIL
''';

    const String after = '''
Example:

<?code-excerpt "$filename (SomeSection)"?>
```dart
A B C
```
''';

    await testInjection(
        before: before, source: source, after: after, filename: filename);
  });

  test('fails if READMEs are changed with --fail-on-change', () async {
    final RepositoryPackage package =
        createFakePackage('a_package', packagesDir);
    package.readmeFile.writeAsStringSync('''
Example:

<?code-excerpt "main.dart (SomeSection)"?>
```dart
X Y Z
```
''');
    package.directory.childFile('main.dart').writeAsStringSync('''
FAIL
// #docregion SomeSection
A B C
// #enddocregion SomeSection
FAIL
''');

    Error? commandError;
    final List<String> output = await runCapturingPrint(
        runner, <String>['update-excerpts', '--fail-on-change'],
        errorHandler: (Error e) {
      commandError = e;
    });

    expect(commandError, isA<ToolExit>());
    expect(
      output.join('\n'),
      contains('The following files have out of date excerpts:'),
    );
  });

  test('does not fail if READMEs are not changed with --fail-on-change',
      () async {
    const String filename = 'main.dart';

    const String readme = '''
Example:

<?code-excerpt "$filename (aa)"?>
```dart
A
```
<?code-excerpt "$filename (bb)"?>
```dart
B
```
''';

    const String source = '''
// #docregion aa
A
// #enddocregion aa
// #docregion bb
B
// #enddocregion bb
''';

    await testInjection(
      before: readme,
      source: source,
      after: readme,
      filename: filename,
      failOnChange: true,
    );
  });

  test('indents the plaster', () async {
    const String filename = 'main.dart';

    const String before = '''
Example:

<?code-excerpt "$filename (SomeSection)"?>
```dart
```
''';

    const String source = '''
// #docregion SomeSection
A
  // #enddocregion SomeSection
// #docregion SomeSection
B
// #enddocregion SomeSection
''';

    const String after = '''
Example:

<?code-excerpt "$filename (SomeSection)"?>
```dart
A
  // ···
B
```
''';

    await testInjection(
        before: before, source: source, after: after, filename: filename);
  });

  test('does not unindent blocks if plaster will not unindent', () async {
    const String filename = 'main.dart';

    const String before = '''
Example:

<?code-excerpt "$filename (SomeSection)"?>
```dart
```
''';

    const String source = '''
// #docregion SomeSection
  A
// #enddocregion SomeSection
// #docregion SomeSection
    B
// #enddocregion SomeSection
''';

    const String after = '''
Example:

<?code-excerpt "$filename (SomeSection)"?>
```dart
  A
// ···
    B
```
''';

    await testInjection(
        before: before, source: source, after: after, filename: filename);
  });

  test('unindents blocks', () async {
    const String filename = 'main.dart';

    const String before = '''
Example:

<?code-excerpt "$filename (SomeSection)"?>
```dart
```
''';

    const String source = '''
  // #docregion SomeSection
  A
  // #enddocregion SomeSection
    // #docregion SomeSection
    B
    // #enddocregion SomeSection
''';

    const String after = '''
Example:

<?code-excerpt "$filename (SomeSection)"?>
```dart
A
// ···
  B
```
''';

    await testInjection(
        before: before, source: source, after: after, filename: filename);
  });

  test('unindents blocks and plaster', () async {
    const String filename = 'main.dart';

    const String before = '''
Example:

<?code-excerpt "$filename (SomeSection)"?>
```dart
```
''';

    const String source = '''
  // #docregion SomeSection
  A
    // #enddocregion SomeSection
    // #docregion SomeSection
    B
    // #enddocregion SomeSection
''';

    const String after = '''
Example:

<?code-excerpt "$filename (SomeSection)"?>
```dart
A
  // ···
  B
```
''';

    await testInjection(
        before: before, source: source, after: after, filename: filename);
  });

  test('relative path bases', () async {
    final RepositoryPackage package =
        createFakePackage('a_package', packagesDir);
    package.readmeFile.writeAsStringSync('''
<?code-excerpt "main.dart (a)"?>
```dart
```
<?code-excerpt "test/main.dart (a)"?>
```dart
```
<?code-excerpt "test/test/main.dart (a)"?>
```dart
```
<?code-excerpt path-base="test"?>
<?code-excerpt "main.dart (a)"?>
```dart
```
<?code-excerpt "../main.dart (a)"?>
```dart
```
<?code-excerpt "test/main.dart (a)"?>
```dart
```
<?code-excerpt path-base="/packages/a_package"?>
<?code-excerpt "main.dart (a)"?>
```dart
```
<?code-excerpt "test/main.dart (a)"?>
```dart
```
''');
    package.directory.childFile('main.dart').writeAsStringSync('''
// #docregion a
X
// #enddocregion a
''');
    package.directory.childDirectory('test').createSync();
    package.directory
        .childDirectory('test')
        .childFile('main.dart')
        .writeAsStringSync('''
// #docregion a
Y
// #enddocregion a
''');
    package.directory
        .childDirectory('test')
        .childDirectory('test')
        .createSync();
    package.directory
        .childDirectory('test')
        .childDirectory('test')
        .childFile('main.dart')
        .writeAsStringSync('''
// #docregion a
Z
// #enddocregion a
''');
    await runCapturingPrint(runner, <String>['update-excerpts']);
    expect(package.readmeFile.readAsStringSync(), '''
<?code-excerpt "main.dart (a)"?>
```dart
X
```
<?code-excerpt "test/main.dart (a)"?>
```dart
Y
```
<?code-excerpt "test/test/main.dart (a)"?>
```dart
Z
```
<?code-excerpt path-base="test"?>
<?code-excerpt "main.dart (a)"?>
```dart
Y
```
<?code-excerpt "../main.dart (a)"?>
```dart
X
```
<?code-excerpt "test/main.dart (a)"?>
```dart
Z
```
<?code-excerpt path-base="/packages/a_package"?>
<?code-excerpt "main.dart (a)"?>
```dart
X
```
<?code-excerpt "test/main.dart (a)"?>
```dart
Y
```
''');
  });

  test('logs snippets checked', () async {
    final RepositoryPackage package =
        createFakePackage('a_package', packagesDir);
    package.readmeFile.writeAsStringSync('''
Example:

<?code-excerpt "main.dart (SomeSection)"?>
```dart
A B C
```
''');
    package.directory.childFile('main.dart').writeAsStringSync('''
FAIL
// #docregion SomeSection
A B C
// #enddocregion SomeSection
FAIL
''');

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

    expect(
      output,
      containsAllInOrder(<Matcher>[
        contains('Checked 1 snippet(s) in README.md.'),
      ]),
    );
  });

  group('File type tests', () {
    const List<Map<String, String>> testCases = <Map<String, String>>[
      <String, String>{'filename': 'main.cc', 'language': 'c++'},
      <String, String>{'filename': 'main.cpp', 'language': 'c++'},
      <String, String>{'filename': 'main.dart'},
      <String, String>{'filename': 'main.js'},
      <String, String>{'filename': 'main.kt', 'language': 'kotlin'},
      <String, String>{'filename': 'main.java'},
      <String, String>{'filename': 'main.gradle', 'language': 'groovy'},
      <String, String>{'filename': 'main.m', 'language': 'objectivec'},
      <String, String>{'filename': 'main.swift'},
      <String, String>{
        'filename': 'main.css',
        'prefix': '/* ',
        'suffix': ' */'
      },
      <String, String>{
        'filename': 'main.html',
        'prefix': '<!--',
        'suffix': '-->'
      },
      <String, String>{
        'filename': 'main.xml',
        'prefix': '<!--',
        'suffix': '-->'
      },
      <String, String>{'filename': 'main.yaml', 'prefix': '# '},
      <String, String>{'filename': 'main.sh', 'prefix': '# '},
      <String, String>{'filename': 'main', 'language': 'txt', 'prefix': ''},
    ];

    void runTest(Map<String, String> testCase) {
      test('updates ${testCase['filename']} files', () async {
        final String filename = testCase['filename']!;
        final String language = testCase['language'] ?? filename.split('.')[1];
        final String prefix = testCase['prefix'] ?? '// ';
        final String suffix = testCase['suffix'] ?? '';

        final String before = '''
Example:

<?code-excerpt "$filename (SomeSection)"?>
```$language
X Y Z
```
''';

        final String source = '''
FAIL
$prefix#docregion SomeSection$suffix
A B C
$prefix#enddocregion SomeSection$suffix
FAIL
''';

        final String after = '''
Example:

<?code-excerpt "$filename (SomeSection)"?>
```$language
A B C
```
''';

        await testInjection(
            before: before, source: source, after: after, filename: filename);
      });
    }

    testCases.forEach(runTest);
  });
}

void main() {
  runAllTests(MockPlatform());
  runAllTests(MockPlatform(isWindows: true));
}
