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

import 'util.dart';

/// A class to represent a line of input code, with associated line number, file
/// and element name.
class SourceLine {
  const SourceLine(
    this.text, {
    this.file,
    this.element,
    this.line = -1,
    this.startChar = -1,
    this.endChar = -1,
    this.indent = 0,
  });
  final File? file;
  final String? element;
  final int line;
  final int startChar;
  final int endChar;
  final int indent;
  final String text;

  String toStringWithColumn(int column) =>
      '$file:$line:${column + indent}: $text';

  SourceLine copyWith({
    String? element,
    String? text,
    File? file,
    int? line,
    int? startChar,
    int? endChar,
    int? indent,
  }) {
    return SourceLine(
      text ?? this.text,
      element: element ?? this.element,
      file: file ?? this.file,
      line: line ?? this.line,
      startChar: startChar ?? this.startChar,
      endChar: endChar ?? this.endChar,
      indent: indent ?? this.indent,
    );
  }

  bool get hasFile => file != null;

  @override
  String toString() => '$file:${line == -1 ? '??' : line}: $text';
}

/// A class containing the name and contents associated with a code block inside of a
/// code sample, for named injection into a template.
class SkeletonInjection {
  SkeletonInjection(this.name, this.contents, {this.language = ''});
  final String name;
  final List<SourceLine> contents;
  final String language;
  Iterable<String> get stringContents =>
      contents.map<String>((SourceLine line) => line.text.trimRight());
  String get mergedContent => stringContents.join('\n');
}

/// A base class to represent a block of any kind of sample code, marked by
/// "{@tool (snippet|sample|dartdoc) ...}...{@end-tool}".
abstract class CodeSample {
  CodeSample(
    this.args,
    this.input, {
    required this.index,
    required SourceLine lineProto,
  })  : assert(args.isNotEmpty),
        _lineProto = lineProto,
        sourceFile = null;

  CodeSample.fromFile(
    this.args,
    this.input,
    this.sourceFile, {
    required this.index,
    required SourceLine lineProto,
  })  : assert(args.isNotEmpty),
        _lineProto = lineProto;

  final File? sourceFile;
  final List<String> args;
  final List<SourceLine> input;
  final SourceLine _lineProto;
  String? _sourceFileContents;
  String get sourceFileContents {
    if (sourceFile != null && _sourceFileContents == null) {
      // Strip lines until the first non-comment line. This gets rid of the
      // copyright and comment directing the reader to the original source file.
      final List<String> stripped = <String>[];
      bool doneStrippingHeaders = false;
      try {
        for (final String line in sourceFile!.readAsLinesSync()) {
          if (!doneStrippingHeaders &&
              RegExp(r'^\s*(\/\/.*)?$').hasMatch(line)) {
            continue;
          }
          // Stop skipping lines after the first line that isn't stripped.
          doneStrippingHeaders = true;
          stripped.add(line);
        }
      } on FileSystemException catch (e) {
        throw SnippetException(
          'Unable to read linked source file ${sourceFile!}: $e',
          file: _lineProto.file?.absolute.path,
        );
      }
      // Remove any section markers
      final RegExp sectionMarkerRegExp = RegExp(
        r'(\/\/\*\*+\n)?\/\/\* [▼▲]+.*$(\n\/\/\*\*+)?\n\n?',
        multiLine: true,
      );
      _sourceFileContents =
          stripped.join('\n').replaceAll(sectionMarkerRegExp, '');
    }
    return _sourceFileContents ?? '';
  }

  Iterable<String> get inputStrings =>
      input.map<String>((SourceLine line) => line.text);
  String get inputAsString => inputStrings.join('\n');

  /// The index of this sample within the dartdoc comment it came from.
  final int index;
  String description = '';
  String get element => start.element ?? '';
  String output = '';
  Map<String, Object?> metadata = <String, Object?>{};
  List<SkeletonInjection> parts = <SkeletonInjection>[];
  SourceLine get start => input.isEmpty ? _lineProto : input.first;

  String get template {
    final ArgParser parser = ArgParser();
    parser.addOption('template', defaultsTo: '');
    final ArgResults parsedArgs = parser.parse(args);
    return parsedArgs['template']! as String;
  }

  @override
  String toString() {
    final StringBuffer buf = StringBuffer('${args.join(' ')}:\n');
    for (final SourceLine line in input) {
      buf.writeln(
        '${(line.line == -1 ? '??' : line.line).toString().padLeft(4)}: ${line.text} ',
      );
    }
    return buf.toString();
  }

  String get type;
}

/// A class to represent a snippet of sample code, marked by "{@tool
/// snippet}...{@end-tool}".
///
/// Snippets are code that is not meant to be run as a complete application, but
/// rather as a code usage example.
class SnippetSample extends CodeSample {
  SnippetSample(
    List<SourceLine> input, {
    required int index,
    required SourceLine lineProto,
  })  : assumptions = <SourceLine>[],
        super(
          <String>['snippet'],
          input,
          index: index,
          lineProto: lineProto,
        );

  factory SnippetSample.combine(
    List<SnippetSample> sections, {
    required int index,
    required SourceLine lineProto,
  }) {
    final List<SourceLine> code =
        sections.expand((SnippetSample section) => section.input).toList();
    return SnippetSample(code, index: index, lineProto: lineProto);
  }

  factory SnippetSample.fromStrings(SourceLine firstLine, List<String> code,
      {required int index}) {
    final List<SourceLine> codeLines = <SourceLine>[];
    int startPos = firstLine.startChar;
    for (int i = 0; i < code.length; ++i) {
      codeLines.add(
        firstLine.copyWith(
          text: code[i],
          line: firstLine.line + i,
          startChar: startPos,
        ),
      );
      startPos += code[i].length + 1;
    }
    return SnippetSample(
      codeLines,
      index: index,
      lineProto: firstLine,
    );
  }

  factory SnippetSample.surround(
    String prefix,
    List<SourceLine> code,
    String postfix, {
    required int index,
  }) {
    return SnippetSample(
      <SourceLine>[
        if (prefix.isNotEmpty) SourceLine(prefix),
        ...code,
        if (postfix.isNotEmpty) SourceLine(postfix),
      ],
      index: index,
      lineProto: code.first,
    );
  }

  List<SourceLine> assumptions;

  @override
  String get template => '';

  @override
  SourceLine get start =>
      input.firstWhere((SourceLine line) => line.file != null);

  @override
  String get type => 'snippet';
}

/// A class to represent a plain application sample in the dartdoc comments,
/// marked by `{@tool sample ...}...{@end-tool}`.
///
/// Application samples are processed separately from [SnippetSample]s, because
/// they must be injected into templates in order to be analyzed. Each
/// [ApplicationSample] represents one `{@tool sample ...}...{@end-tool}` block
/// in the source file.
class ApplicationSample extends CodeSample {
  ApplicationSample({
    List<SourceLine> input = const <SourceLine>[],
    required List<String> args,
    required int index,
    required SourceLine lineProto,
  })  : assert(args.isNotEmpty),
        super(args, input, index: index, lineProto: lineProto);

  ApplicationSample.fromFile({
    List<SourceLine> input = const <SourceLine>[],
    required List<String> args,
    required File sourceFile,
    required int index,
    required SourceLine lineProto,
  })  : assert(args.isNotEmpty),
        super.fromFile(args, input, sourceFile,
            index: index, lineProto: lineProto);

  @override
  String get type => 'sample';
}

/// A class to represent a Dartpad application sample in the dartdoc comments,
/// marked by `{@tool dartpad ...}...{@end-tool}`.
///
/// Dartpad samples are processed separately from [SnippetSample]s, because they
/// must be injected into templates in order to be analyzed. Each
/// [DartpadSample] represents one `{@tool dartpad ...}...{@end-tool}` block in
/// the source file.
class DartpadSample extends ApplicationSample {
  DartpadSample({
    super.input,
    required super.args,
    required super.index,
    required super.lineProto,
  }) : assert(args.isNotEmpty);

  DartpadSample.fromFile({
    super.input,
    required super.args,
    required super.sourceFile,
    required super.index,
    required super.lineProto,
  })  : assert(args.isNotEmpty),
        super.fromFile();

  @override
  String get type => 'dartpad';
}

/// The different types of Dart [SourceElement]s that can be found in a source file.
enum SourceElementType {
  /// A class
  classType,

  /// A field variable of a class.
  fieldType,

  /// A constructor for a class.
  constructorType,

  /// A method of a class.
  methodType,

  /// A function typedef
  typedefType,

  /// A top level (non-class) variable.
  topLevelVariableType,

  /// A function, either top level, or embedded in another function.
  functionType,

  /// An unknown type used for initialization.
  unknownType,
}

/// Converts the enum type [SourceElementType] to a human readable string.
String sourceElementTypeAsString(SourceElementType type) {
  return switch (type) {
    SourceElementType.classType            => 'class',
    SourceElementType.fieldType            => 'field',
    SourceElementType.methodType           => 'method',
    SourceElementType.constructorType      => 'constructor',
    SourceElementType.typedefType          => 'typedef',
    SourceElementType.topLevelVariableType => 'variable',
    SourceElementType.functionType         => 'function',
    SourceElementType.unknownType          => 'unknown',
  };
}

/// A class that represents a Dart element in a source file.
///
/// The element is one of the types in [SourceElementType].
class SourceElement {
  /// A factory constructor for SourceElements.
  ///
  /// This uses a factory so that the default for the `comment` and `samples`
  /// lists can be modifiable lists.
  factory SourceElement(
    SourceElementType type,
    String name,
    int startPos, {
    required File file,
    String className = '',
    List<SourceLine>? comment,
    int startLine = -1,
    List<CodeSample>? samples,
    bool override = false,
  }) {
    comment ??= <SourceLine>[];
    samples ??= <CodeSample>[];
    final List<String> commentLines =
        comment.map<String>((SourceLine line) => line.text).toList();
    final String commentString = commentLines.join('\n');
    return SourceElement._(
      type,
      name,
      startPos,
      file: file,
      className: className,
      comment: comment,
      startLine: startLine,
      samples: samples,
      override: override,
      commentString: commentString,
      commentStringWithoutTools: _getCommentStringWithoutTools(commentString),
      commentStringWithoutCode: _getCommentStringWithoutCode(commentString),
      commentLines: commentLines,
    );
  }

  const SourceElement._(
    this.type,
    this.name,
    this.startPos, {
    required this.file,
    this.className = '',
    this.comment = const <SourceLine>[],
    this.startLine = -1,
    this.samples = const <CodeSample>[],
    this.override = false,
    String commentString = '',
    String commentStringWithoutTools = '',
    String commentStringWithoutCode = '',
    List<String> commentLines = const <String>[],
  })  : _commentString = commentString,
        _commentStringWithoutTools = commentStringWithoutTools,
        _commentStringWithoutCode = commentStringWithoutCode,
        _commentLines = commentLines;

  final String _commentString;
  final String _commentStringWithoutTools;
  final String _commentStringWithoutCode;
  final List<String> _commentLines;

  // Does not include the description of the sample code, just the text outside
  // of any dartdoc tools.
  static String _getCommentStringWithoutTools(String string) {
    return string.replaceAll(
        RegExp(r'(\{@tool ([^}]*)\}.*?\{@end-tool\}|/// ?)', dotAll: true), '');
  }

  // Includes the description text inside of an "@tool"-based sample, but not
  // the code itself, or any dartdoc tags.
  static String _getCommentStringWithoutCode(String string) {
    return string.replaceAll(
        RegExp(r'([`]{3}.*?[`]{3}|\{@\w+[^}]*\}|/// ?)', dotAll: true), '');
  }

  /// The type of the element
  final SourceElementType type;

  /// The name of the element.
  ///
  /// For example, a method called "doSomething" that is part of the class
  /// "MyClass" would have "doSomething" as its name.
  final String name;

  /// The name of the class the element belongs to, if any.
  ///
  /// This is the empty string if it isn't part of a class.
  ///
  /// For example, a method called "doSomething" that is part of the class
  /// "MyClass" would have "MyClass" as its `className`.
  final String className;

  /// Whether or not this element has the "@override" annotation attached to it.
  final bool override;

  /// The file that this [SourceElement] was parsed from.
  final File file;

  /// The character position in the file that this [SourceElement] starts at.
  final int startPos;

  /// The line in the file that the first position of [SourceElement] is on.
  final int startLine;

  /// The list of [SourceLine]s that make up the documentation comment for this
  /// [SourceElement].
  final List<SourceLine> comment;

  /// The list of [CodeSample]s that are in the documentation comment for this
  /// [SourceElement].
  ///
  /// This field will be populated by calling [replaceSamples].
  final List<CodeSample> samples;

  /// Get the comments as an iterable of lines.
  Iterable<String> get commentLines => _commentLines;

  /// Get the comments as a single string.
  String get commentString => _commentString;

  /// Does not include the description of the sample code, just the text outside of any dartdoc tools.
  String get commentStringWithoutTools => _commentStringWithoutTools;

  /// Includes the description text inside of an "@tool"-based sample, but not
  /// the code itself, or any dartdoc tags.
  String get commentStringWithoutCode => _commentStringWithoutCode;

  /// The number of samples in the dartdoc comment for this element.
  int get sampleCount => samples.length;

  /// The number of [DartpadSample]s in the dartdoc comment for this element.
  int get dartpadSampleCount => samples.whereType<DartpadSample>().length;

  /// The number of [ApplicationSample]s in the dartdoc comment for this element.
  int get applicationSampleCount => samples.where((CodeSample sample) {
        return sample is ApplicationSample && sample is! DartpadSample;
      }).length;

  /// The number of [SnippetSample]s in the dartdoc comment for this element.
  int get snippetCount => samples.whereType<SnippetSample>().length;

  /// Count of comment lines, not including lines of code in the comment.
  int get lineCount => commentStringWithoutCode.split('\n').length;

  /// Count of comment words, not including words in any code in the comment.
  int get wordCount {
    return commentStringWithoutCode.split(RegExp(r'\s+')).length;
  }

  /// Count of comment characters, not including any code samples in the
  /// comment, after collapsing each run of whitespace to a single space.
  int get charCount =>
      commentStringWithoutCode.replaceAll(RegExp(r'\s+'), ' ').length;

  /// Whether or not this element's documentation has a "See also:" section in it.
  bool get hasSeeAlso => commentStringWithoutTools.contains('See also:');

  int get referenceCount {
    final RegExp regex = RegExp(r'\[[. \w]*\](?!\(.*\))');
    return regex.allMatches(commentStringWithoutCode).length;
  }

  int get linkCount {
    final RegExp regex = RegExp(r'\[[. \w]*\]\(.*\)');
    return regex.allMatches(commentStringWithoutCode).length;
  }

  /// Returns the fully qualified name of this element.
  ///
  /// For example, a method called "doSomething" that is part of the class
  /// "MyClass" would have "MyClass.doSomething" as its `elementName`.
  String get elementName {
    if (type == SourceElementType.constructorType) {
      // Constructors already have the name of the class in them.
      return name;
    }
    return className.isEmpty ? name : '$className.$name';
  }

  /// Returns the type of this element as a [String].
  String get typeAsString {
    return '${override ? 'overridden ' : ''}${sourceElementTypeAsString(type)}';
  }

  void replaceSamples(Iterable<CodeSample> samples) {
    this.samples.clear();
    this.samples.addAll(samples);
  }

  /// Copy the source element, with some attributes optionally replaced.
  SourceElement copyWith({
    SourceElementType? type,
    String? name,
    int? startPos,
    File? file,
    String? className,
    List<SourceLine>? comment,
    int? startLine,
    List<CodeSample>? samples,
    bool? override,
  }) {
    return SourceElement(
      type ?? this.type,
      name ?? this.name,
      startPos ?? this.startPos,
      file: file ?? this.file,
      className: className ?? this.className,
      comment: comment ?? this.comment,
      startLine: startLine ?? this.startLine,
      samples: samples ?? this.samples,
      override: override ?? this.override,
    );
  }
}
