// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
// for details. 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:analyzer/file_system/file_system.dart';
import 'package:dartdoc/src/dartdoc_options.dart';
import 'package:dartdoc/src/model/model.dart';
import 'package:dartdoc/src/warnings.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'dartdoc_test_base.dart';
import 'src/utils.dart' as utils;

void main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(DocumentationCommentTest);
  });
}

@reflectiveTest
class DocumentationCommentTest extends DartdocTestBase {
  @override
  String get libraryName => 'my_library';

  late Folder projectRoot;
  late PackageGraph packageGraph;
  late ModelElement libraryModel;

  void expectNoWarnings() {
    expect(packageGraph.packageWarningCounter.hasWarnings, isFalse);
    expect(packageGraph.packageWarningCounter.countedWarnings, isEmpty);
  }

  @override
  Future<void> setUp() async {
    await super.setUp();

    projectRoot = utils.writePackage(
        'my_package', resourceProvider, packageConfigProvider);
    projectRoot
        .getChildAssumingFile('dartdoc_options.yaml')
        .writeAsStringSync('''
      dartdoc:
        warnings:
          - missing-code-block-language
      ''');

    projectRoot
        .getChildAssumingFolder('lib')
        .getChildAssumingFile('a.dart')
        .writeAsStringSync('''
/// Documentation comment.
int x = 1;
''');

    var optionSet = DartdocOptionRoot.fromOptionGenerators(
        'dartdoc', [createDartdocOptions], packageMetaProvider);
    optionSet.parseArguments([]);
    packageGraph = await utils.bootBasicPackage(
        projectRoot.path, packageMetaProvider, packageConfigProvider,
        additionalArguments: []);
    libraryModel = packageGraph.defaultPackage.libraries.first;
  }

  void test_removesTripleSlashes() async {
    var doc = await libraryModel.processComment('''
/// Text.
/// More text.
''');

    expect(doc, equals('''
Text.
More text.'''));
  }

  void test_removesSpaceAfterTripleSlashes() async {
    var doc = await libraryModel.processComment('''
///  Text.
///    More text.
''');

    // TODO(srawlins): Actually, the three spaces before 'More' is perhaps not
    // the best fit. Should it only be two, to match the indent from the first
    // line's "Text"?
    expect(doc, equals('''
Text.
   More text.'''));
  }

  void test_leavesBlankLines() async {
    var doc = await libraryModel.processComment('''
/// Text.
///
/// More text.
''');

    expect(doc, equals('''
Text.

More text.'''));
  }

  void test_processesAanimationDirective() async {
    var doc = await libraryModel.processComment('''
/// Text.
///
/// {@animation 100 200 http://host/path/to/video.mp4 id=barHerderAnimation}
///
/// End text.
''');

    expectNoWarnings();
    var rendered = libraryModel.modelElementRenderer.renderAnimation(
        'barHerderAnimation',
        100,
        200,
        Uri.parse('http://host/path/to/video.mp4'),
        'barHerderAnimation_play_button_');
    expect(doc, equals('''
Text.

$rendered

End text.'''));
  }

  void test_rendersUnnamedAnimation() async {
    var doc = await libraryModel.processComment('''
/// First line.
///
/// {@animation 100 200 http://host/path/to/video.mp4}
''');

    expectNoWarnings();
    expect(doc, contains('<video id="animation_1"'));
  }

  void test_rendersNamedAnimation() async {
    var doc = await libraryModel.processComment('''
/// First line.
///
/// {@animation 100 200 http://host/path/to/video.mp4 id=namedAnimation}
''');

    expectNoWarnings();
    expect(doc, contains('<video id="namedAnimation"'));
  }

  void test_rendersNamedAnimation_outOfOrder() async {
    var doc = await libraryModel.processComment('''
/// First line.
///
/// {@animation 100 200 id=namedAnimation http://host/path/to/video.mp4}
''');

    expectNoWarnings();
    expect(doc, contains('<video id="namedAnimation"'));
  }

  void test_rendersNamedAnimationWithDoubleQuotes() async {
    var doc = await libraryModel.processComment('''
/// First line.
///
/// {@animation 100 200 http://host/path/to/video.mp4 id="namedAnimation"}
''');

    expectNoWarnings();
    expect(doc, contains('<video id="namedAnimation"'));
  }

  void test_rendersNamedAnimationWithSingleQuotes() async {
    var doc = await libraryModel.processComment('''
/// First line.
///
/// {@animation 100 200 http://host/path/to/video.mp4 id='namedAnimation'}
''');

    expectNoWarnings();
    expect(doc, contains('<video id="namedAnimation"'));
  }

  void test_rendersMultipleAnimationsUsingUniqueIds() async {
    var doc = await libraryModel.processComment('''
/// First line.
///
/// {@animation 100 200 http://host/path/to/video.mp4}
/// {@animation 100 200 http://host/path/to/video2.mp4}
''');

    expectNoWarnings();
    expect(doc, contains('<video id="animation_1"'));
    expect(doc, contains('<video id="animation_2"'));

    // A second element with unnamed animations requires unique IDs as well.
    doc = await libraryModel.processComment('''
/// First line.
///
/// {@animation 100 200 http://host/path/to/video.mp4}
/// {@animation 100 200 http://host/path/to/video2.mp4}
''');

    expectNoWarnings();
    expect(doc, contains('<video id="animation_3"'));
    expect(doc, contains('<video id="animation_4"'));
  }

  void test_animationDirectiveHasFewerThanThreeArguments() async {
    await libraryModel.processComment('''
/// Text.
///
/// {@animation 100 http://host/path/to/video.mp4 id=barHerderAnimation}
///
/// End text.
''');

    expect(
        libraryModel,
        hasInvalidParameterWarning(
            'Invalid @animation directive, "{@animation 100 '
            'http://host/path/to/video.mp4 id=barHerderAnimation}"\n'
            'Animation directives must be of the form "{@animation WIDTH '
            'HEIGHT URL [id=ID]}"'));
  }

  void test_animationDirectiveHasMoreThanFourArguments() async {
    await libraryModel.processComment('''
/// Text.
///
/// {@animation 100 200 300 400 http://host/path/to/video.mp4 id=barHerderAnimation}
///
/// End text.
''');

    expect(
        libraryModel,
        hasInvalidParameterWarning(
            'Invalid @animation directive, "{@animation 100 200 300 400 '
            'http://host/path/to/video.mp4 id=barHerderAnimation}"\n'
            'Animation directives must be of the form "{@animation WIDTH '
            'HEIGHT URL [id=ID]}"'));
  }

  void test_animationDirectiveHasNonUniqueIdentifier() async {
    await libraryModel.processComment('''
/// Text.
///
/// {@animation 100 200 http://host/path/to/video.mp4 id=barHerderAnimation}
/// {@animation 100 200 http://host/path/to/video.mpg id=barHerderAnimation}
///
/// End text.
''');

    expect(
        libraryModel,
        hasInvalidParameterWarning('An animation has a non-unique identifier, '
            '"barHerderAnimation". Animation identifiers must be unique.'));
  }

  void test_animationDirectiveHasAnInvalidIdentifier() async {
    await libraryModel.processComment('''
/// Text.
///
/// {@animation 100 200 http://host/path/to/video.mp4 id=not-valid}
///
/// End text.
''');

    expect(
        libraryModel,
        hasInvalidParameterWarning(
            'An animation has an invalid identifier, "not-valid". The '
            'identifier can only contain letters, numbers and underscores, and '
            'must not begin with a number.'));
  }

  void test_animationDirectiveHasMalformedWidth() async {
    await libraryModel.processComment('''
/// Text.
///
/// {@animation 100px 200 http://host/path/to/video.mp4 id=barHerderAnimation}
///
/// End text.
''');

    expect(
        libraryModel,
        hasInvalidParameterWarning(
            'An animation has an invalid width (barHerderAnimation), '
            '"100px". The width must be an integer.'));
  }

  void test_animationDirectiveHasMalformedHeight() async {
    await libraryModel.processComment('''
/// Text.
///
/// {@animation 100 200px http://host/path/to/video.mp4 id=barHerderAnimation}
///
/// End text.
''');

    expect(
        libraryModel,
        hasInvalidParameterWarning(
            'An animation has an invalid height (barHerderAnimation), '
            '"200px". The height must be an integer.'));
  }

  void test_animationDirectiveHasUnknownParameter() async {
    await libraryModel.processComment('''
/// Text.
///
/// {@animation 100 200 http://host/path/to/video.mp4 name=barHerderAnimation}
///
/// End text.
''');

    expect(
        libraryModel,
        hasInvalidParameterWarning(
            'The {@animation ...} directive was called with invalid '
            'parameters. FormatException: Could not find an option named '
            '"name".'));
  }

  void test_processesTemplateDirective() async {
    var doc = await libraryModel.processComment('''
/// Text.
///
/// {@template abc}
/// Template text.
/// {@endtemplate}
///
/// End text.
''');

    expectNoWarnings();
    expect(doc, equals('''
Text.

{@macro abc}

End text.'''));
  }

  void test_processesLeadingTemplateDirective() async {
    var doc = await libraryModel.processComment('''
/// {@template abc}
/// Template text.
/// {@endtemplate}
///
/// End text.
''');

    expectNoWarnings();
    expect(doc, equals('''
{@macro abc}

End text.'''));
  }

  void test_processesTrailingTemplateDirective() async {
    var doc = await libraryModel.processComment('''
/// Text.
///
/// {@template abc}
/// Template text.
/// {@endtemplate}
''');

    expectNoWarnings();
    expect(doc, equals('''
Text.

{@macro abc}'''));
  }

  void test_processesTemplateDirectiveWithoutBlankLineFollowing() async {
    var doc = await libraryModel.processComment('''
/// Text.
///
/// {@template abc}
/// Template text.
/// {@endtemplate}
/// End text.
''');

    expectNoWarnings();
    expect(doc, equals('''
Text.

{@macro abc}
End text.'''));
  }

  void test_allowsWhitespaceAroundTemplateDirectiveName() async {
    var doc = await libraryModel.processComment('''
/// {@template    abc    }
/// Template text.
/// {@endtemplate}
''');

    expectNoWarnings();
    expect(doc, equals('{@macro abc}'));
  }

  void test_processesExampleDirectiveWithFile() async {
    projectRoot.getChildAssumingFile('abc.md').writeAsStringSync('''
```plaintext
Code snippet
```
''');
    var doc = await libraryModel.processComment('''
/// Text.
///
/// {@example abc}
///
/// End text.
''');

    expect(
      libraryModel,
      hasDeprecatedWarning(
        "The '@example' directive is deprecated, and will soon no longer be "
        'supported.',
      ),
    );
    expect(doc, equals('''
Text.

```plaintext
Code snippet
```


End text.'''));
  }

  void test_processesExampleDirectiveWithRegion() async {
    projectRoot
        .getChildAssumingFile('abc-r.md')
        .writeAsStringSync('Markdown text.');
    var doc = await libraryModel.processComment('''
/// Text.
///
/// {@example region=r abc}
''');

    expect(
      libraryModel,
      hasDeprecatedWarning(
        "The '@example' directive is deprecated, and will soon no longer be "
        'supported.',
      ),
    );
    expect(doc, equals('''
Text.

Markdown text.'''));
  }

  void test_addsLanguageToProcessedExampleWithExtensionAndNoLang() async {
    projectRoot.getChildAssumingFile('abc.html.md').writeAsStringSync('''
```
Code snippet
```
''');
    var doc = await libraryModel.processComment('''
/// Text.
///
/// {@example abc.html}
///
/// End text.
''');

    expect(
      libraryModel,
      hasDeprecatedWarning(
        "The '@example' directive is deprecated, and will soon no longer be "
        'supported.',
      ),
    );
    expect(doc, equals('''
Text.

```html
Code snippet
```


End text.'''));
  }

  void test_addsLanguageToProcessedExampleWithLangAndAnExtension() async {
    projectRoot.getChildAssumingFile('abc.html.md').writeAsStringSync('''
```
Code snippet
```
''');
    var doc = await libraryModel.processComment('''
/// Text.
///
/// {@example abc.html lang=html}
''');

    expect(
      libraryModel,
      hasDeprecatedWarning(
        "The '@example' directive is deprecated, and will soon no longer be "
        'supported.',
      ),
    );
    expect(doc, equals('''
Text.

```html
Code snippet
```
'''));
  }

  void
      test_addsLanguageToProcessedExampleDirectiveWithLangAndNoExtension() async {
    projectRoot.getChildAssumingFile('abc.md').writeAsStringSync('''
```
Code snippet
```
''');
    var doc = await libraryModel.processComment('''
/// Text.
///
/// {@example abc lang=html}
''');

    expect(
      libraryModel,
      hasDeprecatedWarning(
        "The '@example' directive is deprecated, and will soon no longer be "
        'supported.',
      ),
    );
    expect(doc, equals('''
Text.

```html
Code snippet
```
'''));
  }

  void test_processesExampleDirectiveWithFileNotFound() async {
    var doc = await libraryModel.processComment('''
/// {@example abc}
''');

    var abcPath = resourceProvider.pathContext.canonicalize(
        resourceProvider.pathContext.join(projectRoot.path, 'abc.md'));
    var libPathInWarning = resourceProvider.pathContext.join('lib', 'a.dart');
    expect(
      libraryModel,
      hasDeprecatedWarning(
        "The '@example' directive is deprecated, and will soon no longer be "
        'supported.',
      ),
    );
    expect(libraryModel,
        hasMissingExampleWarning('$abcPath; path listed at $libPathInWarning'));
    // When the example path is invalid, the directive should be left in-place.
    expect(doc, equals('{@example abc}'));
  }

  void test_processesExampleDirectiveWithDirectoriesNotFound() async {
    var doc = await libraryModel.processComment('''
/// {@example abc/def/ghi}
''');
    var abcPath = resourceProvider.pathContext.canonicalize(resourceProvider
        .pathContext
        .join(projectRoot.path, 'abc', 'def', 'ghi.md'));
    var libPathInWarning = resourceProvider.pathContext.join('lib', 'a.dart');
    expect(libraryModel,
        hasMissingExampleWarning('$abcPath; path listed at $libPathInWarning'));
    // When the example path is invalid, the directive should be left in-place.
    expect(doc, equals('{@example abc/def/ghi}'));
  }

  void test_processesExampleDirectiveWithRegionNotFound() async {
    var doc = await libraryModel.processComment('''
/// {@example region=r abc}
''');
    var abcPath = resourceProvider.pathContext.canonicalize(
        resourceProvider.pathContext.join(projectRoot.path, 'abc-r.md'));
    var libPathInWarning = resourceProvider.pathContext.join('lib', 'a.dart');
    expect(libraryModel,
        hasMissingExampleWarning('$abcPath; path listed at $libPathInWarning'));
    // When the example path is invalid, the directive should be left in-place.
    expect(doc, equals('{@example region=r abc}'));
  }

  void test_leavesInjectHtmlDirectiveUnprocessedWhenDisabled() async {
    var doc = await libraryModel.processComment('''
/// Text.
///
/// {@inject-html}<script></script>{@end-inject-html}
''');

    expectNoWarnings();
    expect(doc, equals('''
Text.

{@inject-html}<script></script>{@end-inject-html}'''));
  }

  void test_leavesToolUnprocessedWhenDisabled() async {
    var doc = await libraryModel.processComment('''
/// Text.
///
/// {@tool date}{@end-tool}
''');

    expectNoWarnings();
    expect(doc, equals('''
Text.

{@tool date}{@end-tool}'''));
  }

  void test_processesInjectHtmlDirectiveWhenEnabled() async {
    packageGraph = await utils.bootBasicPackage(
        projectRoot.path, packageMetaProvider, packageConfigProvider,
        additionalArguments: ['--inject-html']);
    libraryModel = packageGraph.defaultPackage.libraries.first;
    var doc = await libraryModel.processComment('''
/// Text.
///
/// {@inject-html}<script></script>{@end-inject-html}
''');

    expectNoWarnings();
    expect(doc, equals('''
Text.


<dartdoc-html>6829def5ec06d211fa90fe69a58213ae901f3ee4</dartdoc-html>
'''));
  }

  void test_processesYoutubeDirective() async {
    var doc = await libraryModel.processComment('''
/// Text.
///
/// {@youtube 100 200 https://www.youtube.com/watch?v=oHg5SJYRHA0}
///
/// End text.
''');

    expectNoWarnings();
    expect(
      doc,
      matches(
        RegExp(
          '^Text.\n\n+'
          r'<iframe src="https://www.youtube.com/embed/oHg5SJYRHA0\?rel=0".*</iframe>\s*\n\n+'
          r'End text.$',
          multiLine: true,
          dotAll: true,
        ),
      ),
    );
  }

  void test_processesLeadingYoutubeDirective() async {
    var doc = await libraryModel.processComment('''
/// {@youtube 100 200 https://www.youtube.com/watch?v=oHg5SJYRHA0}
///
/// End text.
''');

    expectNoWarnings();
    expect(
      doc,
      matches(
        RegExp(
          r'<iframe src="https://www.youtube.com/embed/oHg5SJYRHA0\?rel=0".*</iframe>\s*\n\n+'
          r'End text.$',
          multiLine: true,
          dotAll: true,
        ),
      ),
    );
  }

  void test_processesTrailingYoutubeDirective() async {
    var doc = await libraryModel.processComment('''
/// Text.
///
/// {@youtube 100 200 https://www.youtube.com/watch?v=oHg5SJYRHA0}
''');

    expectNoWarnings();
    expect(
      doc,
      matches(
        RegExp(
          '^Text.\n\n+'
          r'<iframe src="https://www.youtube.com/embed/oHg5SJYRHA0\?rel=0".*</iframe>\s*$',
          multiLine: true,
          dotAll: true,
        ),
      ),
    );
  }

  void test_youtubeDirectiveHasLessThanThreeArguments() async {
    await libraryModel.processComment(
        '/// {@youtube 100 https://www.youtube.com/watch?v=oHg5SJYRHA0}');

    expect(
        libraryModel,
        hasInvalidParameterWarning('Invalid @youtube directive, '
            '"{@youtube 100 https://www.youtube.com/watch?v=oHg5SJYRHA0}"\n'
            'YouTube directives must be of the form '
            '"{@youtube WIDTH HEIGHT URL}"'));
  }

  void test_youtubeDirectiveHasMoreThanThreeArguments() async {
    await libraryModel.processComment(
        '/// {@youtube 100 200 300 https://www.youtube.com/watch?v=oHg5SJYRHA0}');

    expect(
        libraryModel,
        hasInvalidParameterWarning('Invalid @youtube directive, '
            '"{@youtube 100 200 300 https://www.youtube.com/watch?v=oHg5SJYRHA0}"\n'
            'YouTube directives must be of the form '
            '"{@youtube WIDTH HEIGHT URL}"'));
  }

  void test_youtubeDirectiveHasMalformedWidth() async {
    await libraryModel.processComment(
        '/// {@youtube 100px 200 https://www.youtube.com/watch?v=oHg5SJYRHA0}');

    expect(
        libraryModel,
        hasInvalidParameterWarning(
            'A @youtube directive has an invalid width, "100px". '
            'The width must be a positive integer.'));
  }

  void test_youtubeDirectiveHasNegativeWidth() async {
    await libraryModel.processComment(
        '/// {@youtube -100 200 https://www.youtube.com/watch?v=oHg5SJYRHA0}');

    expect(
        libraryModel,
        hasInvalidParameterWarning(
            'The {@youtube ...} directive was called with invalid '
            'parameters. FormatException: Could not find an option with '
            'short name "-1".'));
  }

  void test_youtubeDirectiveHasMalformedHeight() async {
    await libraryModel.processComment(
        '/// {@youtube 100 200px https://www.youtube.com/watch?v=oHg5SJYRHA0}');

    expect(
        libraryModel,
        hasInvalidParameterWarning(
            'A @youtube directive has an invalid height, "200px". The height '
            'must be a positive integer.'));
  }

  void test_youtubeDirectiveHasNegativeHeight() async {
    await libraryModel.processComment(
        '/// {@youtube 100 -200 https://www.youtube.com/watch?v=oHg5SJYRHA0}');

    expect(
        libraryModel,
        hasInvalidParameterWarning(
            'The {@youtube ...} directive was called with invalid '
            'parameters. FormatException: Could not find an option with '
            'short name "-2".'));
  }

  void test_youtubeDirectiveHasInvalidUrl() async {
    await libraryModel.processComment(
        '/// {@youtube 100 200 https://www.not-youtube.com/watch?v=oHg5SJYRHA0}');

    expect(
        libraryModel,
        hasInvalidParameterWarning('A @youtube directive has an invalid URL: '
            '"https://www.not-youtube.com/watch?v=oHg5SJYRHA0". Supported '
            'YouTube URLs have the following format: '
            'https://www.youtube.com/watch?v=oHg5SJYRHA0.'));
  }

  void test_youtubeDirectiveHasUrlWithExtraQueryParameters() async {
    await libraryModel.processComment(
        '/// {@youtube 100 200 https://www.not-youtube.com/watch?v=oHg5SJYRHA0&a=1}');

    expect(
        libraryModel,
        hasInvalidParameterWarning('A @youtube directive has an invalid URL: '
            '"https://www.not-youtube.com/watch?v=oHg5SJYRHA0&a=1". '
            'Supported YouTube URLs have the following format: '
            'https://www.youtube.com/watch?v=oHg5SJYRHA0.'));
  }

  void test_fencedCodeBlockDoesNotSpecifyLanguage() async {
    await libraryModel.processComment('''
/// ```
/// void main() {}
/// ```
''');

    expect(
        packageGraph.packageWarningCounter.hasWarning(
            libraryModel,
            PackageWarning.missingCodeBlockLanguage,
            'A fenced code block in Markdown should have a language specified'),
        isTrue);
  }

  void test_squigglyFencedCodeBlockDoesNotSpecifyLanguage() async {
    await libraryModel.processComment('''
/// ~~~
/// void main() {}
/// ~~~
''');

    expect(
        packageGraph.packageWarningCounter.hasWarning(
            libraryModel,
            PackageWarning.missingCodeBlockLanguage,
            'A fenced code block in Markdown should have a language specified'),
        isTrue);
  }

  void test_fencedCodeBlockDoesSpecifyLanguage() async {
    await libraryModel.processComment('''
/// ```dart
/// void main() {}
/// ```
''');

    expect(
        packageGraph.packageWarningCounter.hasWarning(
            libraryModel,
            PackageWarning.missingCodeBlockLanguage,
            'A fenced code block in Markdown should have a language specified'),
        isFalse);
  }

  void test_fencedBlockIsNotClosed() async {
    await libraryModel.processComment('''
/// ```
/// A not closed fenced code block
''');

    expect(
        packageGraph.packageWarningCounter.hasWarning(
            libraryModel,
            PackageWarning.missingCodeBlockLanguage,
            'A fenced code block in Markdown should have a language specified'),
        isFalse);
  }

  Matcher hasDeprecatedWarning(String message) =>
      _HasWarning(PackageWarning.deprecated, message);

  Matcher hasInvalidParameterWarning(String message) =>
      _HasWarning(PackageWarning.invalidParameter, message);

  Matcher hasMissingExampleWarning(String message) =>
      _HasWarning(PackageWarning.missingExampleFile, message);

// TODO(srawlins): More unit tests: @tool.
}

class _HasWarning extends Matcher {
  final PackageWarning kind;

  final String message;

  _HasWarning(this.kind, this.message);

  @override
  bool matches(Object? actual, Map<Object?, Object?> matchState) {
    if (actual is ModelElement) {
      return actual.packageGraph.packageWarningCounter
          .hasWarning(actual, kind, message);
    } else {
      return false;
    }
  }

  @override
  Description describe(Description description) =>
      description.add('Library to be warned with $kind and message:\n$message');

  @override
  Description describeMismatch(Object? actual, Description mismatchDescription,
      Map<Object?, Object?> matchState, bool verbose) {
    if (actual is ModelElement) {
      var warnings = actual
          .packageGraph.packageWarningCounter.countedWarnings[actual.element];
      if (warnings == null) {
        return mismatchDescription.add('has no warnings');
      }
      if (warnings.length == 1) {
        var kind = warnings.keys.first;
        return mismatchDescription
            .add('has one $kind warnings: ${warnings[kind]}');
      }

      return mismatchDescription.add('has warnings: $warnings');
    }

    return mismatchDescription.add('is a ${actual.runtimeType}');
  }
}
