// 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.countedWarnings, isEmpty);
    expect(packageGraph.packageWarningCounter.hasWarnings, isFalse);
  }

  Future<void> writePackageWithCommentedLibraries(
    List<(String, String)> filesAndComments, {
    List<String> additionalArguments = const [],
  }) async {
    projectRoot = utils.writePackage(
        'my_package', resourceProvider, packageConfigProvider);
    projectRoot
        .getChildAssumingFile('dartdoc_options.yaml')
        .writeAsStringSync('''
      dartdoc:
        warnings:
          - missing-code-block-language
      ''');

    for (var (fileName, comment) in filesAndComments) {
      projectRoot
          .getChildAssumingFolder('lib')
          .getChildAssumingFile(fileName)
          .writeAsStringSync('$comment\n'
              'library;');
    }

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

  Future<void> writePackageWithCommentedLibrary(
    String comment, {
    List<String> additionalArguments = const [],
  }) =>
      writePackageWithCommentedLibraries([('a.dart', comment)],
          additionalArguments: additionalArguments);

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

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

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

    // 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 {
    await writePackageWithCommentedLibrary('''
/// Text.
///
/// More text.
''');
    var doc = libraryModel.documentation;

    expect(doc, equals('''
Text.

More text.'''));
  }

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

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


<div style="position: relative;">
  <div id="barHerderAnimation_play_button_"
       onclick="var barHerderAnimation = document.getElementById('barHerderAnimation');
                if (barHerderAnimation.paused) {
                  barHerderAnimation.play();
                  this.style.display = 'none';
                } else {
                  barHerderAnimation.pause();
                  this.style.display = 'block';
                }"
       style="position:absolute;
              width:100px;
              height:200px;
              z-index:100000;
              background-position: center;
              background-repeat: no-repeat;
              background-image: url(static-assets/play_button.svg);">
  </div>
  <video id="barHerderAnimation"
         style="width:100px; height:200px;"
         onclick="var barHerderAnimation_play_button_ = document.getElementById('barHerderAnimation_play_button_');
                  if (this.paused) {
                    this.play();
                    barHerderAnimation_play_button_.style.display = 'none';
                  } else {
                    this.pause();
                    barHerderAnimation_play_button_.style.display = 'block';
                  }" loop>
    <source src="http://host/path/to/video.mp4" type="video/mp4"/>
  </video>
</div>



End text.'''));
  }

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

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

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

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

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

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

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

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

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

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

  void test_rendersMultipleAnimationsUsingUniqueIds() async {
    await writePackageWithCommentedLibraries([
      (
        'a.dart',
        '''
/// First line.
///
/// {@animation 100 200 http://host/path/to/video.mp4}
/// {@animation 100 200 http://host/path/to/video2.mp4}
''',
      ),
      // A second element with unnamed animations requires unique IDs as well.
      (
        'b.dart',
        '''
/// First line.
///
/// {@animation 100 200 http://host/path/to/video.mp4}
/// {@animation 100 200 http://host/path/to/video2.mp4}
''',
      ),
    ]);
    var docA = await libraryModel.processComment();
    var docB = packageGraph.defaultPackage.libraries[1].documentation;

    expectNoWarnings();
    expect(docA, contains('<video id="animation_3"'));
    expect(docA, contains('<video id="animation_4"'));
    expect(docB, contains('<video id="animation_1"'));
    expect(docB, contains('<video id="animation_2"'));
  }

  void test_docImport() async {
    await writePackageWithCommentedLibrary('''
/// Text.
///
/// @docImport 'dart:async' as async;
///
/// End text.
''');
    var doc = libraryModel.documentation;

    expect(doc, equals('''
Text.



End text.'''));
  }

  void test_docImport_onlyLine() async {
    await writePackageWithCommentedLibrary('''
/// @docImport 'dart:async' as async;
''');
    var doc = libraryModel.documentation;

    expect(doc, equals(''));
  }

  void test_docImport_onlyLine_moreWhitespace() async {
    await writePackageWithCommentedLibrary('''
///   @docImport   'dart:async'   as   async;
''');
    var doc = libraryModel.documentation;

    expect(doc, equals(''));
  }

  void test_docImport_consecutiveLines() async {
    await writePackageWithCommentedLibrary('''
/// @docImport 'dart:async' as async;
/// @docImport 'dart:isolate' as isolate;
/// @docImport 'dart:math' as math;
''');
    var doc = libraryModel.documentation;

    expect(doc, equals(''));
  }

  void test_docImport_multipleLines() async {
    await writePackageWithCommentedLibrary('''
/// One.
/// @docImport 'dart:async' as async;
/// Two.
/// @docImport 'dart:isolate' as isolate;
/// Three.
''');
    var doc = libraryModel.documentation;

    expect(doc, equals('''
One.

Two.

Three.'''));
  }

  void test_docImport_precedingText() async {
    await writePackageWithCommentedLibrary('''
// Copyright such-and-such.

/// @docImport 'dart:async' as async;
''');
    var doc = libraryModel.documentation;

    expect(doc, equals(''));
  }

  void test_animationDirectiveHasFewerThanThreeArguments() async {
    await writePackageWithCommentedLibrary('''
/// 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 writePackageWithCommentedLibrary('''
/// 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 writePackageWithCommentedLibrary('''
/// 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 writePackageWithCommentedLibrary('''
/// 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 writePackageWithCommentedLibrary('''
/// 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 writePackageWithCommentedLibrary('''
/// 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 writePackageWithCommentedLibrary('''
/// 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'),
    );
  }

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

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

{@macro abc}

End text.'''));
  }

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

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

End text.'''));
  }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  void test_processesInjectHtmlDirectiveWhenEnabled() async {
    await writePackageWithCommentedLibrary(
      additionalArguments: ['--inject-html'],
      '''
/// Text.
///
/// {@inject-html}<script></script>{@end-inject-html}
''',
    );
    libraryModel = packageGraph.defaultPackage.libraries.first;
    var doc = libraryModel.documentation;

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


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

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

    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 {
    await writePackageWithCommentedLibrary('''
/// {@youtube 100 200 https://www.youtube.com/watch?v=oHg5SJYRHA0}
///
/// End text.
''');
    var doc = libraryModel.documentation;

    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 {
    await writePackageWithCommentedLibrary('''
/// Text.
///
/// {@youtube 100 200 https://www.youtube.com/watch?v=oHg5SJYRHA0}
''');
    var doc = libraryModel.documentation;

    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 writePackageWithCommentedLibrary(
        '/// {@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 writePackageWithCommentedLibrary(
        '/// {@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 writePackageWithCommentedLibrary(
        '/// {@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 writePackageWithCommentedLibrary(
        '/// {@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 writePackageWithCommentedLibrary(
        '/// {@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 writePackageWithCommentedLibrary(
        '/// {@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 writePackageWithCommentedLibrary(
        '/// {@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 writePackageWithCommentedLibrary(
        '/// {@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 writePackageWithCommentedLibrary('''
/// ```
/// 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 writePackageWithCommentedLibrary('''
/// ~~~
/// 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 writePackageWithCommentedLibrary('''
/// ```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 writePackageWithCommentedLibrary('''
/// ```
/// 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);

// 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.element2];
      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}');
  }
}
