// Copyright 2014 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:file/file.dart';
import 'package:file/memory.dart';
import 'package:path/path.dart' as path;
import 'package:platform/platform.dart';
import 'package:pub_semver/pub_semver.dart';
import 'package:snippets/snippets.dart';
import 'package:test/test.dart' hide TypeMatcher, isInstanceOf;

import '../bin/snippets.dart' as snippets_main;
import 'fake_process_manager.dart';

class FakeFlutterInformation extends FlutterInformation {
  FakeFlutterInformation(this.flutterRoot);

  final Directory flutterRoot;

  @override
  Directory getFlutterRoot() {
    return flutterRoot;
  }

  @override
  Map<String, dynamic> getFlutterInformation() {
    return <String, dynamic>{
      'flutterRoot': flutterRoot,
      'frameworkVersion': Version(2, 10, 0),
      'dartSdkVersion': Version(2, 12, 1),
    };
  }
}

void main() {
  group('Generator', () {
    late var memoryFileSystem = MemoryFileSystem();
    late FlutterRepoSnippetConfiguration configuration;
    late SnippetGenerator generator;
    late Directory tmpDir;

    void writeSkeleton(String type) {
      switch (type) {
        case 'dartpad':
          configuration.getHtmlSkeletonFile('dartpad').writeAsStringSync('''
<div>HTML Bits (DartPad-style)</div>
<iframe class="snippet-dartpad" src="https://dartpad.dev/embed-flutter.html?split=60&run=true&sample_id={{id}}&sample_channel={{channel}}"></iframe>
<div>More HTML Bits</div>
''');
        case 'sample':
        case 'snippet':
          configuration.getHtmlSkeletonFile(type).writeAsStringSync('''
<div>HTML Bits</div>
{{description}}
<pre>{{code}}</pre>
<pre>{{app}}</pre>
<div>More HTML Bits</div>
''');
      }
    }

    setUp(() {
      // Create a new filesystem.
      memoryFileSystem = MemoryFileSystem();
      tmpDir = memoryFileSystem.systemTempDirectory.createTempSync('flutter_snippets_test.');
      configuration = FlutterRepoSnippetConfiguration(
        flutterRoot: memoryFileSystem.directory(path.join(tmpDir.absolute.path, 'flutter')),
        filesystem: memoryFileSystem,
      );
      configuration.skeletonsDirectory.createSync(recursive: true);
      <String>['dartpad', 'sample', 'snippet'].forEach(writeSkeleton);
      FlutterInformation.instance = FakeFlutterInformation(configuration.flutterRoot);
      generator = SnippetGenerator(
        configuration: configuration,
        filesystem: memoryFileSystem,
        flutterRoot: configuration.skeletonsDirectory.parent,
      );
    });

    test('generates samples', () async {
      final File inputFile =
          memoryFileSystem.file(path.join(tmpDir.absolute.path, 'snippet_in.txt'))
            ..createSync(recursive: true)
            ..writeAsStringSync(r'''
A description of the sample.

On several lines.

** See code in examples/api/widgets/foo/foo_example.0.dart **
''');
      final String examplePath = path.join(
        configuration.flutterRoot.path,
        'examples/api/widgets/foo/foo_example.0.dart',
      );
      final File exampleFile = memoryFileSystem.file(examplePath);
      await exampleFile.create(recursive: true);
      exampleFile.writeAsStringSync('''
// Copyright

// Flutter code sample for [MyElement].

void main() {
  runApp(MaterialApp(title: 'foo'));
}\n''');
      final File outputFile = memoryFileSystem.file(
        path.join(tmpDir.absolute.path, 'snippet_out.txt'),
      );
      final sampleParser = SnippetDartdocParser(memoryFileSystem);
      const sourcePath = 'packages/flutter/lib/src/widgets/foo.dart';
      const sourceLine = 222;
      final SourceElement element = sampleParser.parseFromDartdocToolFile(
        inputFile,
        element: 'MyElement',
        startLine: sourceLine,
        sourceFile: memoryFileSystem.file(sourcePath),
        type: 'sample',
      );

      expect(element.samples, isNotEmpty);
      element.samples.first.metadata.addAll(<String, Object?>{'channel': 'stable'});
      final String code = generator.generateCode(element.samples.first, output: outputFile);
      expect(code, contains("runApp(MaterialApp(title: 'foo'));"));
      final String html = generator.generateHtml(element.samples.first);
      expect(html, contains('<div>HTML Bits</div>'));
      expect(html, contains('<div>More HTML Bits</div>'));
      expect(html, contains(r'''runApp(MaterialApp(title: &#39;foo&#39;));'''));
      expect(html, isNot(contains('sample_channel=stable')));
      expect(
        html,
        contains(
          'A description of the sample.\n'
          '\n'
          'On several lines.{@inject-html}</div>',
        ),
      );
      expect(html, contains('void main() {'));

      final String outputContents = outputFile.readAsStringSync();
      expect(outputContents, contains('void main() {'));
    });

    test('generates snippets', () async {
      final File inputFile =
          memoryFileSystem.file(path.join(tmpDir.absolute.path, 'snippet_in.txt'))
            ..createSync(recursive: true)
            ..writeAsStringSync(r'''
A description of the snippet.

On several lines.

```code
void main() {
  print('The actual $name.');
}
```
''');

      final sampleParser = SnippetDartdocParser(memoryFileSystem);
      const sourcePath = 'packages/flutter/lib/src/widgets/foo.dart';
      const sourceLine = 222;
      final SourceElement element = sampleParser.parseFromDartdocToolFile(
        inputFile,
        element: 'MyElement',
        startLine: sourceLine,
        sourceFile: memoryFileSystem.file(sourcePath),
        type: 'snippet',
      );
      expect(element.samples, isNotEmpty);
      element.samples.first.metadata.addAll(<String, Object>{'channel': 'stable'});
      final String code = generator.generateCode(element.samples.first);
      expect(code, contains('// A description of the snippet.'));
      final String html = generator.generateHtml(element.samples.first);
      expect(html, contains('<div>HTML Bits</div>'));
      expect(html, contains('<div>More HTML Bits</div>'));
      expect(html, contains(r'  print(&#39;The actual $name.&#39;);'));
      expect(
        html,
        contains(
          '<div class="snippet-description">{@end-inject-html}A description of the snippet.\n\n'
          'On several lines.{@inject-html}</div>\n',
        ),
      );
      expect(html, contains('main() {'));
    });

    test('generates dartpad samples', () async {
      final File inputFile =
          memoryFileSystem.file(path.join(tmpDir.absolute.path, 'snippet_in.txt'))
            ..createSync(recursive: true)
            ..writeAsStringSync(r'''
A description of the snippet.

On several lines.

** See code in examples/api/widgets/foo/foo_example.0.dart **
''');
      final String examplePath = path.join(
        configuration.flutterRoot.path,
        'examples/api/widgets/foo/foo_example.0.dart',
      );
      final File exampleFile = memoryFileSystem.file(examplePath);
      await exampleFile.create(recursive: true);
      exampleFile.writeAsStringSync('''
// Copyright

// Flutter code sample for [MyElement].

void main() {
  runApp(MaterialApp(title: 'foo'));
}\n''');

      final sampleParser = SnippetDartdocParser(memoryFileSystem);
      const sourcePath = 'packages/flutter/lib/src/widgets/foo.dart';
      const sourceLine = 222;
      final SourceElement element = sampleParser.parseFromDartdocToolFile(
        inputFile,
        element: 'MyElement',
        startLine: sourceLine,
        sourceFile: memoryFileSystem.file(sourcePath),
        type: 'dartpad',
      );
      expect(element.samples, isNotEmpty);
      element.samples.first.metadata.addAll(<String, Object>{'channel': 'stable'});
      final String code = generator.generateCode(element.samples.first);
      expect(code, contains("runApp(MaterialApp(title: 'foo'));"));
      final String html = generator.generateHtml(element.samples.first);
      expect(html, contains('<div>HTML Bits (DartPad-style)</div>'));
      expect(html, contains('<div>More HTML Bits</div>'));
      expect(
        html,
        contains(
          '<iframe class="snippet-dartpad" src="https://dartpad.dev/embed-flutter.html?split=60&run=true&sample_id=MyElement.0&sample_channel=stable"></iframe>\n',
        ),
      );
    });

    test('generates sample metadata', () async {
      final File inputFile =
          memoryFileSystem.file(path.join(tmpDir.absolute.path, 'snippet_in.txt'))
            ..createSync(recursive: true)
            ..writeAsStringSync(r'''
A description of the snippet.

On several lines.

```dart
void main() {
  print('The actual $name.');
}
```
''');

      final File outputFile = memoryFileSystem.file(
        path.join(tmpDir.absolute.path, 'snippet_out.dart'),
      );
      final File expectedMetadataFile = memoryFileSystem.file(
        path.join(tmpDir.absolute.path, 'snippet_out.json'),
      );

      final sampleParser = SnippetDartdocParser(memoryFileSystem);
      const sourcePath = 'packages/flutter/lib/src/widgets/foo.dart';
      const sourceLine = 222;
      final SourceElement element = sampleParser.parseFromDartdocToolFile(
        inputFile,
        element: 'MyElement',
        startLine: sourceLine,
        sourceFile: memoryFileSystem.file(sourcePath),
        type: 'sample',
      );
      expect(element.samples, isNotEmpty);
      element.samples.first.metadata.addAll(<String, Object>{'channel': 'stable'});
      generator.generateCode(element.samples.first, output: outputFile);
      expect(expectedMetadataFile.existsSync(), isTrue);
      final json = jsonDecode(expectedMetadataFile.readAsStringSync()) as Map<String, dynamic>;
      expect(json['id'], equals('MyElement.0'));
      expect(json['channel'], equals('stable'));
      expect(json['file'], equals('snippet_out.dart'));
      expect(json['description'], equals('A description of the snippet.\n\nOn several lines.'));
      expect(json['sourcePath'], equals('packages/flutter/lib/src/widgets/foo.dart'));
    });
  });

  group('snippets command line argument test', () {
    late var memoryFileSystem = MemoryFileSystem();
    late Directory tmpDir;
    late Directory flutterRoot;
    late FakeProcessManager fakeProcessManager;

    setUp(() {
      fakeProcessManager = FakeProcessManager();
      memoryFileSystem = MemoryFileSystem();
      tmpDir = memoryFileSystem.systemTempDirectory.createTempSync('flutter_snippets_test.');
      flutterRoot = memoryFileSystem.directory(path.join(tmpDir.absolute.path, 'flutter'))
        ..createSync(recursive: true);
    });

    test('command line arguments are parsed and passed to generator', () {
      final platform = FakePlatform(
        environment: <String, String>{
          'PACKAGE_NAME': 'dart:ui',
          'LIBRARY_NAME': 'library',
          'ELEMENT_NAME': 'element',
          'FLUTTER_ROOT': flutterRoot.absolute.path,
          // The details here don't really matter other than the flutter root.
          'FLUTTER_VERSION':
              '''
      {
        "frameworkVersion": "2.5.0-6.0.pre.55",
        "channel": "use_snippets_pkg",
        "repositoryUrl": "git@github.com:flutter/flutter.git",
        "frameworkRevision": "fec4641e1c88923ecd6c969e2ff8a0dd12dc0875",
        "frameworkCommitDate": "2021-08-11 15:19:48 -0700",
        "engineRevision": "d8bbebed60a77b3d4fe9c840dc94dfbce159d951",
        "dartSdkVersion": "2.14.0 (build 2.14.0-393.0.dev)",
        "flutterRoot": "${flutterRoot.absolute.path}"
      }''',
        },
      );
      final flutterInformation = FlutterInformation(
        filesystem: memoryFileSystem,
        processManager: fakeProcessManager,
        platform: platform,
      );
      FlutterInformation.instance = flutterInformation;
      var mockSnippetGenerator = MockSnippetGenerator();
      snippets_main.snippetGenerator = mockSnippetGenerator;
      var errorMessage = '';
      errorExit = (String message) {
        errorMessage = message;
      };

      snippets_main.platform = platform;
      snippets_main.filesystem = memoryFileSystem;
      snippets_main.processManager = fakeProcessManager;
      final File input = memoryFileSystem.file(tmpDir.childFile('input.snippet'))
        ..writeAsString('/// Test file');
      snippets_main.main(<String>['--input=${input.absolute.path}']);

      final Map<String, dynamic> metadata = mockSnippetGenerator.sample.metadata;
      // Ignore the channel, because channel is really just the branch, and will be
      // different on development workstations.
      metadata.remove('channel');
      expect(
        metadata,
        equals(<String, dynamic>{
          'id': 'dart_ui.library.element',
          'element': 'element',
          'sourcePath': 'unknown.dart',
          'sourceLine': 1,
          'serial': '',
          'package': 'dart:ui',
          'library': 'library',
        }),
      );

      snippets_main.main(<String>[]);
      expect(
        errorMessage,
        equals(
          'The --input option must be specified, either on the command line, or in the INPUT environment variable.',
        ),
      );
      errorMessage = '';

      snippets_main.main(<String>['--input=${input.absolute.path}', '--type=snippet']);
      expect(errorMessage, equals(''));
      errorMessage = '';

      mockSnippetGenerator = MockSnippetGenerator();
      snippets_main.snippetGenerator = mockSnippetGenerator;
      snippets_main.main(<String>[
        '--input=${input.absolute.path}',
        '--type=snippet',
        '--no-format-output',
      ]);
      expect(mockSnippetGenerator.formatOutput, equals(false));
      errorMessage = '';

      input.deleteSync();
      snippets_main.main(<String>['--input=${input.absolute.path}']);
      expect(errorMessage, equals('The input file ${input.absolute.path} does not exist.'));
      errorMessage = '';
    });
  });
}

class MockSnippetGenerator extends SnippetGenerator {
  late CodeSample sample;
  File? output;
  String? copyright;
  String? description;
  late bool formatOutput;
  late bool addSectionMarkers;
  late bool includeAssumptions;

  @override
  String generateCode(
    CodeSample sample, {
    File? output,
    String? copyright,
    String? description,
    bool formatOutput = true,
    bool addSectionMarkers = false,
    bool includeAssumptions = false,
  }) {
    this.sample = sample;
    this.output = output;
    this.copyright = copyright;
    this.description = description;
    this.formatOutput = formatOutput;
    this.addSectionMarkers = addSectionMarkers;
    this.includeAssumptions = includeAssumptions;

    return '';
  }

  @override
  String generateHtml(CodeSample sample) {
    return '';
  }
}
