// 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:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/utilities.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/file_system/file_system.dart' as afs;
import 'package:analyzer/file_system/physical_file_system.dart' as afs;
import 'package:analyzer/source/line_info.dart';
import 'package:file/file.dart';

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

/// Gets an iterable over all of the blocks of documentation comments in a file
/// using the analyzer.
///
/// Each entry in the list is a list of source lines corresponding to the
/// documentation comment block.
Iterable<List<SourceLine>> getFileDocumentationComments(File file) {
  return getDocumentationComments(getFileElements(file));
}

/// Gets an iterable over all of the blocks of documentation comments from an
/// iterable over the [SourceElement]s involved.
Iterable<List<SourceLine>> getDocumentationComments(Iterable<SourceElement> elements) {
  return elements
      .where((SourceElement element) => element.comment.isNotEmpty)
      .map<List<SourceLine>>((SourceElement element) => element.comment);
}

/// Gets an iterable over the comment [SourceElement]s in a file.
Iterable<SourceElement> getFileCommentElements(File file) {
  return getCommentElements(getFileElements(file));
}

/// Filters the source `elements` to only return the comment elements.
Iterable<SourceElement> getCommentElements(Iterable<SourceElement> elements) {
  return elements.where((SourceElement element) => element.comment.isNotEmpty);
}

/// Reads the file content from a string, to avoid having to read the file more
/// than once if the caller already has the content in memory.
///
/// The `file` argument is used to tag the lines with a filename that they came from.
Iterable<SourceElement> getElementsFromString(String content, File file) {
  final ParseStringResult parseResult = parseString(
    featureSet: FeatureSet.fromEnableFlags2(
      sdkLanguageVersion: FlutterInformation.instance.getDartSdkVersion(),
      flags: <String>[],
    ),
    content: content,
  );
  final visitor = _SourceVisitor<CompilationUnit>(file);
  visitor.visitCompilationUnit(parseResult.unit);
  visitor.assignLineNumbers();
  return visitor.elements;
}

/// Gets an iterable over the [SourceElement]s in the given `file`.
///
/// Takes an optional [ResourceProvider] to allow reading from a memory
/// filesystem.
Iterable<SourceElement> getFileElements(File file, {afs.ResourceProvider? resourceProvider}) {
  resourceProvider ??= afs.PhysicalResourceProvider.INSTANCE;
  final ParseStringResult parseResult = parseFile(
    featureSet: FeatureSet.fromEnableFlags2(
      sdkLanguageVersion: FlutterInformation.instance.getDartSdkVersion(),
      flags: <String>[],
    ),
    path: file.absolute.path,
    resourceProvider: resourceProvider,
  );
  final visitor = _SourceVisitor<CompilationUnit>(file);
  visitor.visitCompilationUnit(parseResult.unit);
  visitor.assignLineNumbers();
  return visitor.elements;
}

class _SourceVisitor<T> extends RecursiveAstVisitor<T> {
  _SourceVisitor(this.file) : elements = <SourceElement>{};

  final Set<SourceElement> elements;
  String enclosingClass = '';

  File file;

  void assignLineNumbers() {
    final String contents = file.readAsStringSync();
    final lineInfo = LineInfo.fromContent(contents);

    final removedElements = <SourceElement>{};
    final replacedElements = <SourceElement>{};
    for (final SourceElement element in elements) {
      final newLines = <SourceLine>[];
      for (final SourceLine line in element.comment) {
        final CharacterLocation intervalLine = lineInfo.getLocation(line.startChar);
        newLines.add(line.copyWith(line: intervalLine.lineNumber));
      }
      final int elementLine = lineInfo.getLocation(element.startPos).lineNumber;
      replacedElements.add(element.copyWith(comment: newLines, startLine: elementLine));
      removedElements.add(element);
    }
    elements.removeAll(removedElements);
    elements.addAll(replacedElements);
  }

  List<SourceLine> _processComment(String element, Comment comment) {
    final result = <SourceLine>[];
    if (comment.tokens.isNotEmpty) {
      for (final Token token in comment.tokens) {
        result.add(
          SourceLine(
            token.toString(),
            element: element,
            file: file,
            startChar: token.charOffset,
            endChar: token.charEnd,
          ),
        );
      }
    }
    return result;
  }

  @override
  T? visitCompilationUnit(CompilationUnit node) {
    elements.clear();
    return super.visitCompilationUnit(node);
  }

  static bool isPublic(String name) {
    return !name.startsWith('_');
  }

  static bool isInsideMethod(AstNode startNode) {
    AstNode? node = startNode.parent;
    while (node != null) {
      if (node is MethodDeclaration) {
        return true;
      }
      node = node.parent;
    }
    return false;
  }

  @override
  T? visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
    for (final VariableDeclaration declaration in node.variables.variables) {
      if (!isPublic(declaration.name.lexeme)) {
        continue;
      }
      var comment = <SourceLine>[];
      if (node.documentationComment != null && node.documentationComment!.tokens.isNotEmpty) {
        comment = _processComment(declaration.name.lexeme, node.documentationComment!);
      }
      elements.add(
        SourceElement(
          SourceElementType.topLevelVariableType,
          declaration.name.lexeme,
          node.beginToken.charOffset,
          file: file,
          className: enclosingClass,
          comment: comment,
        ),
      );
    }
    return super.visitTopLevelVariableDeclaration(node);
  }

  @override
  T? visitGenericTypeAlias(GenericTypeAlias node) {
    if (isPublic(node.name.lexeme)) {
      var comment = <SourceLine>[];
      if (node.documentationComment != null && node.documentationComment!.tokens.isNotEmpty) {
        comment = _processComment(node.name.lexeme, node.documentationComment!);
      }
      elements.add(
        SourceElement(
          SourceElementType.typedefType,
          node.name.lexeme,
          node.beginToken.charOffset,
          file: file,
          comment: comment,
        ),
      );
    }
    return super.visitGenericTypeAlias(node);
  }

  @override
  T? visitFieldDeclaration(FieldDeclaration node) {
    for (final VariableDeclaration declaration in node.fields.variables) {
      if (!isPublic(declaration.name.lexeme) || !isPublic(enclosingClass)) {
        continue;
      }
      var comment = <SourceLine>[];
      if (node.documentationComment != null && node.documentationComment!.tokens.isNotEmpty) {
        assert(enclosingClass.isNotEmpty);
        comment = _processComment(
          '$enclosingClass.${declaration.name.lexeme}',
          node.documentationComment!,
        );
      }
      elements.add(
        SourceElement(
          SourceElementType.fieldType,
          declaration.name.lexeme,
          node.beginToken.charOffset,
          file: file,
          className: enclosingClass,
          comment: comment,
          override: _isOverridden(node),
        ),
      );
      return super.visitFieldDeclaration(node);
    }
    return null;
  }

  @override
  T? visitConstructorDeclaration(ConstructorDeclaration node) {
    final fullName = '$enclosingClass${node.name == null ? '' : '.${node.name}'}';
    if (isPublic(enclosingClass) && (node.name == null || isPublic(node.name!.lexeme))) {
      var comment = <SourceLine>[];
      if (node.documentationComment != null && node.documentationComment!.tokens.isNotEmpty) {
        comment = _processComment('$enclosingClass.$fullName', node.documentationComment!);
      }
      elements.add(
        SourceElement(
          SourceElementType.constructorType,
          fullName,
          node.beginToken.charOffset,
          file: file,
          className: enclosingClass,
          comment: comment,
        ),
      );
    }
    return super.visitConstructorDeclaration(node);
  }

  @override
  T? visitFunctionDeclaration(FunctionDeclaration node) {
    if (isPublic(node.name.lexeme)) {
      var comment = <SourceLine>[];
      // Skip functions that are defined inside of methods.
      if (!isInsideMethod(node)) {
        if (node.documentationComment != null && node.documentationComment!.tokens.isNotEmpty) {
          comment = _processComment(node.name.lexeme, node.documentationComment!);
        }
        elements.add(
          SourceElement(
            SourceElementType.functionType,
            node.name.lexeme,
            node.beginToken.charOffset,
            file: file,
            comment: comment,
            override: _isOverridden(node),
          ),
        );
      }
    }
    return super.visitFunctionDeclaration(node);
  }

  @override
  T? visitMethodDeclaration(MethodDeclaration node) {
    if (isPublic(node.name.lexeme) && isPublic(enclosingClass)) {
      var comment = <SourceLine>[];
      if (node.documentationComment != null && node.documentationComment!.tokens.isNotEmpty) {
        assert(enclosingClass.isNotEmpty);
        comment = _processComment(
          '$enclosingClass.${node.name.lexeme}',
          node.documentationComment!,
        );
      }
      elements.add(
        SourceElement(
          SourceElementType.methodType,
          node.name.lexeme,
          node.beginToken.charOffset,
          file: file,
          className: enclosingClass,
          comment: comment,
          override: _isOverridden(node),
        ),
      );
    }
    return super.visitMethodDeclaration(node);
  }

  bool _isOverridden(AnnotatedNode node) {
    return node.metadata.where((Annotation annotation) {
      return annotation.name.name == 'override';
    }).isNotEmpty;
  }

  @override
  T? visitMixinDeclaration(MixinDeclaration node) {
    enclosingClass = node.name.lexeme;
    if (!node.name.lexeme.startsWith('_')) {
      enclosingClass = node.name.lexeme;
      var comment = <SourceLine>[];
      if (node.documentationComment != null && node.documentationComment!.tokens.isNotEmpty) {
        comment = _processComment(node.name.lexeme, node.documentationComment!);
      }
      elements.add(
        SourceElement(
          SourceElementType.classType,
          node.name.lexeme,
          node.beginToken.charOffset,
          file: file,
          comment: comment,
        ),
      );
    }
    final T? result = super.visitMixinDeclaration(node);
    enclosingClass = '';
    return result;
  }

  @override
  T? visitClassDeclaration(ClassDeclaration node) {
    enclosingClass = node.name.lexeme;
    if (!node.name.lexeme.startsWith('_')) {
      enclosingClass = node.name.lexeme;
      var comment = <SourceLine>[];
      if (node.documentationComment != null && node.documentationComment!.tokens.isNotEmpty) {
        comment = _processComment(node.name.lexeme, node.documentationComment!);
      }
      elements.add(
        SourceElement(
          SourceElementType.classType,
          node.name.lexeme,
          node.beginToken.charOffset,
          file: file,
          comment: comment,
        ),
      );
    }
    final T? result = super.visitClassDeclaration(node);
    enclosingClass = '';
    return result;
  }
}
