// 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 'package:file/file.dart';
import 'package:path/path.dart' as path;

import 'data_types.dart';
import 'util.dart';

/// Parses [CodeSample]s from the source file given to one of the parsing routines.
///
/// - [parseFromDartdocToolFile] parses the output of the dartdoc `@tool`
///   directive, which contains the dartdoc comment lines (with comment markers
///   stripped) contained between the tool markers.
///
/// - [parseAndAddAssumptions] parses the assumptions in the "Examples can
///   assume:" block at the top of the file and adds them to the code samples
///   contained in the given [SourceElement] iterable.
class SnippetDartdocParser {
  SnippetDartdocParser(this.filesystem);

  final FileSystem filesystem;

  /// The prefix of each comment line
  static const String _dartDocPrefix = '///';

  /// The prefix of each comment line with a space appended.
  static const String _dartDocPrefixWithSpace = '$_dartDocPrefix ';

  /// A RegExp that matches the beginning of a dartdoc snippet or sample.
  static final RegExp _dartDocSampleBeginRegex =
      RegExp(r'\{@tool (?<type>sample|snippet|dartpad)(?:| (?<args>[^}]*))\}');

  /// A RegExp that matches the end of a dartdoc snippet or sample.
  static final RegExp _dartDocSampleEndRegex = RegExp(r'\{@end-tool\}');

  /// A RegExp that matches the start of a code block within dartdoc.
  static final RegExp _codeBlockStartRegex = RegExp(r'///\s+```dart.*$');

  /// A RegExp that matches the end of a code block within dartdoc.
  static final RegExp _codeBlockEndRegex = RegExp(r'///\s+```\s*$');

  /// A RegExp that matches a linked sample pointer.
  static final RegExp _filePointerRegex =
      RegExp(r'\*\* See code in (?<file>[^\]]+) \*\*');

  /// Parses the assumptions in the "Examples can assume:" block at the top of
  /// the `assumptionsFile` and adds them to the code samples contained in the
  /// given `elements` iterable.
  void parseAndAddAssumptions(
    Iterable<SourceElement> elements,
    File assumptionsFile, {
    bool silent = true,
  }) {
    final List<SourceLine> assumptions = parseAssumptions(assumptionsFile);
    for (final CodeSample sample in elements
        .expand<CodeSample>((SourceElement element) => element.samples)) {
      if (sample is SnippetSample) {
        sample.assumptions = assumptions;
      }
      sample.metadata.addAll(<String, Object?>{
        'id': '${sample.element}.${sample.index}',
        'element': sample.element,
        'sourcePath': assumptionsFile.path,
        'sourceLine': sample.start.line,
      });
    }
  }

  /// Parses a file containing the output of the dartdoc `@tool` directive,
  /// which contains the dartdoc comment lines (with comment markers stripped)
  /// between the tool markers.
  ///
  /// This is meant to be run as part of a dartdoc tool that handles snippets.
  SourceElement parseFromDartdocToolFile(
    File input, {
    int? startLine,
    String? element,
    required File sourceFile,
    String type = '',
    bool silent = true,
  }) {
    final List<SourceLine> lines = <SourceLine>[];
    int lineNumber = startLine ?? 0;
    final List<String> inputStrings = <String>[
      // The parser wants to read the arguments from the input, so we create a new
      // tool line to match the given arguments, so that we can use the same parser for
      // editing and docs generation.
      '/// {@tool $type}',
      // Snippet input comes in with the comment markers stripped, so we add them
      // back to make it conform to the source format, so we can use the same
      // parser for editing samples as we do for processing docs.
      ...input
          .readAsLinesSync()
          .map<String>((String line) => '/// $line'.trimRight()),
      '/// {@end-tool}',
    ];
    for (final String line in inputStrings) {
      lines.add(
        SourceLine(line,
            element: element ?? '', line: lineNumber, file: sourceFile),
      );
      lineNumber++;
    }
    // No need to get assumptions: dartdoc won't give that to us.
    final SourceElement newElement = SourceElement(
        SourceElementType.unknownType, element!, -1,
        file: input, comment: lines);
    parseFromComments(<SourceElement>[newElement], silent: silent);
    for (final CodeSample sample in newElement.samples) {
      sample.metadata.addAll(<String, Object?>{
        'id': '${sample.element}.${sample.index}',
        'element': sample.element,
        'sourcePath': sourceFile.path,
        'sourceLine': sample.start.line,
      });
    }
    return newElement;
  }

  /// This parses the assumptions in the "Examples can assume:" block from the
  /// given `file`.
  List<SourceLine> parseAssumptions(File file) {
    // Whether or not we're in the file-wide preamble section ("Examples can assume").
    bool inPreamble = false;
    final List<SourceLine> preamble = <SourceLine>[];
    int lineNumber = 0;
    int charPosition = 0;
    for (final String line in file.readAsLinesSync()) {
      if (inPreamble && line.trim().isEmpty) {
        // Reached the end of the preamble.
        break;
      }
      if (!line.startsWith('// ')) {
        lineNumber++;
        charPosition += line.length + 1;
        continue;
      }
      if (line == '// Examples can assume:') {
        inPreamble = true;
        lineNumber++;
        charPosition += line.length + 1;
        continue;
      }
      if (inPreamble) {
        preamble.add(SourceLine(
          line.substring(3),
          startChar: charPosition,
          endChar: charPosition + line.length + 1,
          element: '#assumptions',
          file: file,
          line: lineNumber,
        ));
      }
      lineNumber++;
      charPosition += line.length + 1;
    }
    return preamble;
  }

  /// This parses the code snippets from the documentation comments in the given
  /// `elements`, and sets the resulting samples as the `samples` member of
  /// each element in the supplied iterable.
  void parseFromComments(
    Iterable<SourceElement> elements, {
    bool silent = true,
  }) {
    int dartpadCount = 0;
    int sampleCount = 0;
    int snippetCount = 0;

    for (final SourceElement element in elements) {
      if (element.comment.isEmpty) {
        continue;
      }
      parseComment(element);
      for (final CodeSample sample in element.samples) {
        switch (sample) {
          case DartpadSample _:
            dartpadCount++;
          case ApplicationSample _:
            sampleCount++;
          case SnippetSample _:
            snippetCount++;
        }
      }
    }

    if (!silent) {
      print('Found:\n'
          '  $snippetCount snippet code blocks,\n'
          '  $sampleCount non-dartpad sample code sections, and\n'
          '  $dartpadCount dartpad sections.\n');
    }
  }

  /// This parses the documentation comment on a single [SourceElement] and
  /// assigns the resulting samples to the `samples` member of the given
  /// `element`.
  void parseComment(SourceElement element) {
    // Whether or not we're in a snippet code sample.
    bool inSnippet = false;
    // Whether or not we're in a '```dart' segment.
    bool inDart = false;
    bool foundSourceLink = false;
    bool foundDartSection = false;
    File? linkedFile;
    List<SourceLine> block = <SourceLine>[];
    List<String> snippetArgs = <String>[];
    final List<CodeSample> samples = <CodeSample>[];
    final Directory flutterRoot = FlutterInformation.instance.getFlutterRoot();

    int index = 0;
    for (final SourceLine line in element.comment) {
      final String trimmedLine = line.text.trim();
      if (inSnippet) {
        if (!trimmedLine.startsWith(_dartDocPrefix)) {
          throw SnippetException('Snippet section unterminated.',
              file: line.file?.path, line: line.line);
        }
        if (_dartDocSampleEndRegex.hasMatch(trimmedLine)) {
          switch (snippetArgs.first) {
            case 'snippet':
              samples.add(
                SnippetSample(
                  block,
                  index: index++,
                  lineProto: line,
                ),
              );
            case 'sample':
              if (linkedFile != null) {
                samples.add(
                  ApplicationSample.fromFile(
                    input: block,
                    args: snippetArgs,
                    sourceFile: linkedFile,
                    index: index++,
                    lineProto: line,
                  ),
                );
                break;
              }
              samples.add(
                ApplicationSample(
                  input: block,
                  args: snippetArgs,
                  index: index++,
                  lineProto: line,
                ),
              );
            case 'dartpad':
              if (linkedFile != null) {
                samples.add(
                  DartpadSample.fromFile(
                    input: block,
                    args: snippetArgs,
                    sourceFile: linkedFile,
                    index: index++,
                    lineProto: line,
                  ),
                );
                break;
              }
              samples.add(
                DartpadSample(
                  input: block,
                  args: snippetArgs,
                  index: index++,
                  lineProto: line,
                ),
              );
            default:
              throw SnippetException(
                  'Unknown snippet type ${snippetArgs.first}');
          }
          snippetArgs = <String>[];
          block = <SourceLine>[];
          inSnippet = false;
          foundSourceLink = false;
          foundDartSection = false;
          linkedFile = null;
        } else if (_filePointerRegex.hasMatch(trimmedLine)) {
          foundSourceLink = true;
          if (foundDartSection) {
            throw SnippetException(
              'Snippet contains a source link and a dart section. Cannot contain both.',
              file: line.file?.path,
              line: line.line,
            );
          }
          if (linkedFile != null) {
            throw SnippetException(
              'Found more than one linked sample. Only one linked file per sample is allowed.',
              file: line.file?.path,
              line: line.line,
            );
          }
          final RegExpMatch match = _filePointerRegex.firstMatch(trimmedLine)!;
          linkedFile = filesystem.file(
              path.join(flutterRoot.absolute.path, match.namedGroup('file')));
        } else {
          block.add(line.copyWith(
              text: line.text.replaceFirst(RegExp(r'\s*/// ?'), '')));
        }
      } else {
        if (_dartDocSampleEndRegex.hasMatch(trimmedLine)) {
          if (inDart) {
            throw SnippetException(
                "Dart section didn't terminate before end of sample",
                file: line.file?.path,
                line: line.line);
          }
        }
        if (inDart) {
          if (_codeBlockEndRegex.hasMatch(trimmedLine)) {
            inDart = false;
            block = <SourceLine>[];
          } else if (trimmedLine == _dartDocPrefix) {
            block.add(line.copyWith(text: ''));
          } else {
            final int index = line.text.indexOf(_dartDocPrefixWithSpace);
            if (index < 0) {
              throw SnippetException(
                'Dart section inexplicably did not contain "$_dartDocPrefixWithSpace" prefix.',
                file: line.file?.path,
                line: line.line,
              );
            }
            block.add(line.copyWith(text: line.text.substring(index + 4)));
          }
        } else if (_codeBlockStartRegex.hasMatch(trimmedLine)) {
          if (foundSourceLink) {
            throw SnippetException(
              'Snippet contains a source link and a dart section. Cannot contain both.',
              file: line.file?.path,
              line: line.line,
            );
          }
          assert(block.isEmpty);
          inDart = true;
          foundDartSection = true;
        }
      }
      if (!inSnippet && !inDart) {
        final RegExpMatch? sampleMatch =
            _dartDocSampleBeginRegex.firstMatch(trimmedLine);
        if (sampleMatch != null) {
          inSnippet = sampleMatch.namedGroup('type') == 'snippet' ||
              sampleMatch.namedGroup('type') == 'sample' ||
              sampleMatch.namedGroup('type') == 'dartpad';
          if (inSnippet) {
            if (sampleMatch.namedGroup('args') != null) {
              // There are arguments to the snippet tool to keep track of.
              snippetArgs = <String>[
                sampleMatch.namedGroup('type')!,
                ..._splitUpQuotedArgs(sampleMatch.namedGroup('args')!)
              ];
            } else {
              snippetArgs = <String>[
                sampleMatch.namedGroup('type')!,
              ];
            }
          }
        }
      }
    }
    for (final CodeSample sample in samples) {
      sample.metadata.addAll(<String, Object?>{
        'id': '${sample.element}.${sample.index}',
        'element': sample.element,
        'sourcePath': sample.start.file?.path ?? '',
        'sourceLine': sample.start.line,
      });
    }
    element.replaceSamples(samples);
  }

  // Helper to process arguments given as a (possibly quoted) string.
  //
  // First, this will split the given [argsAsString] into separate arguments,
  // taking any quoting (either ' or " are accepted) into account, including
  // handling backslash-escaped quotes.
  //
  // Then, it will prepend "--" to any args that start with an identifier
  // followed by an equals sign, allowing the argument parser to treat any
  // "foo=bar" argument as "--foo=bar" (which is a dartdoc-ism).
  Iterable<String> _splitUpQuotedArgs(String argsAsString) {
    // This function is used because the arg parser package doesn't handle
    // quoted args.

    // Regexp to take care of splitting arguments, and handling the quotes
    // around arguments, if any.
    //
    // Match group 1 (option) is the "foo=" (or "--foo=") part of the option, if any.
    // Match group 2 (quote) contains the quote character used (which is discarded).
    // Match group 3 (value) is a quoted arg, if any, without the quotes.
    // Match group 4 (unquoted) is the unquoted arg, if any.
    final RegExp argMatcher = RegExp(
        r'(?<option>[-_a-zA-Z0-9]+=)?' // option name
        r'(?:' // Start a new non-capture group for the two possibilities.
        r'''(?<quote>["'])(?<value>(?:\\{2})*|(?:.*?[^\\](?:\\{2})*))\2|''' // value with quotes.
        r'(?<unquoted>[^ ]+))'); // without quotes.
    final Iterable<RegExpMatch> matches = argMatcher.allMatches(argsAsString);

    // Remove quotes around args, then for any args that look like assignments
    // (start with valid option names followed by an equals sign), add a "--" in
    // front so that they parse as options to support legacy dartdoc
    // functionality of "option=value".
    return matches.map<String>((RegExpMatch match) {
      String option = '';
      if (match.namedGroup('option') != null &&
          !match.namedGroup('option')!.startsWith('-')) {
        option = '--';
      }
      if (match.namedGroup('quote') != null) {
        // This arg has quotes, so strip them.
        return '$option'
            '${match.namedGroup('value') ?? ''}'
            '${match.namedGroup('unquoted') ?? ''}';
      }
      return '$option${match[0]}';
    });
  }
}
