// Copyright (c) 2019, 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/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/error/codes.dart';

/// Instances of the class `ToDoFinder` find to-do comments in Dart code.
class TodoFinder {
  /// The error reporter by which to-do comments will be reported.
  final ErrorReporter _errorReporter;

  /// A regex for whitespace and comment markers to be removed from the text
  /// of multiline TODOs in multiline comments.
  final RegExp _commentNewlineAndMarker = RegExp('\\s*\\n\\s*\\*\\s*');

  /// A regex for any character that is not a comment marker `/` or whitespace
  /// used for finding the first "real" character of a comment to compare its
  /// indentation for wrapped todos.
  final RegExp _nonWhitespaceOrCommentMarker = RegExp('[^/ ]');

  /// Initialize a newly created to-do finder to report to-do comments to the
  /// given reporter.
  ///
  /// @param errorReporter the error reporter by which to-do comments will be
  ///        reported
  TodoFinder(this._errorReporter);

  /// Search the comments in the given compilation unit for to-do comments and
  /// report an error for each.
  ///
  /// @param unit the compilation unit containing the to-do comments
  void findIn(CompilationUnit unit) {
    _gatherTodoComments(unit.beginToken, unit.lineInfo!);
  }

  /// Search the comment tokens reachable from the given token and create errors
  /// for each to-do comment.
  ///
  /// @param token the head of the list of tokens being searched
  void _gatherTodoComments(Token? token, LineInfo lineInfo) {
    while (token != null && token.type != TokenType.EOF) {
      Token? commentToken = token.precedingComments;
      while (commentToken != null) {
        if (commentToken.type == TokenType.SINGLE_LINE_COMMENT ||
            commentToken.type == TokenType.MULTI_LINE_COMMENT) {
          commentToken = _scrapeTodoComment(commentToken, lineInfo);
        } else {
          commentToken = commentToken.next;
        }
      }
      token = token.next;
    }
  }

  /// Look for user defined tasks in comments starting [commentToken] and convert
  /// them into info level analysis issues.
  ///
  /// Subsequent comments that are indented with an additional space are
  /// considered continuations and will be included in a single analysis issue.
  ///
  /// Returns the next comment token to begin searching from (skipping over
  /// any continuations).
  Token? _scrapeTodoComment(Token commentToken, LineInfo lineInfo) {
    Iterable<RegExpMatch> matches =
        TodoCode.TODO_REGEX.allMatches(commentToken.lexeme);
    // Track the comment that will be returned for looking for the next todo.
    // This will be moved along if additional comments are consumed by multiline
    // TODOs.
    var nextComment = commentToken.next;
    final commentLocation = lineInfo.getLocation(commentToken.offset);

    for (RegExpMatch match in matches) {
      int offset = commentToken.offset + match.start + match.group(1)!.length;
      int column =
          commentLocation.columnNumber + match.start + match.group(1)!.length;
      String todoText = match.group(2)!;
      String todoKind = match.namedGroup('kind1') ?? match.namedGroup('kind2')!;
      int end = offset + todoText.length;

      if (commentToken.type == TokenType.MULTI_LINE_COMMENT) {
        // Remove any `*/` and trim any trailing whitespace.
        if (todoText.endsWith('*/')) {
          todoText = todoText.substring(0, todoText.length - 2).trimRight();
          end = offset + todoText.length;
        }

        // Replace out whitespace/comment markers to unwrap multiple lines.
        // Do not reset length after this, as length must include all characters.
        todoText = todoText.replaceAll(_commentNewlineAndMarker, ' ');
      } else if (commentToken.type == TokenType.SINGLE_LINE_COMMENT) {
        // Append any indented lines onto the end.
        var line = commentLocation.lineNumber;
        while (nextComment != null) {
          final nextCommentLocation = lineInfo.getLocation(nextComment.offset);
          final columnOfFirstNoneMarkerOrWhitespace =
              nextCommentLocation.columnNumber +
                  nextComment.lexeme.indexOf(_nonWhitespaceOrCommentMarker);

          final isContinuation =
              nextComment.type == TokenType.SINGLE_LINE_COMMENT &&
                  // Only consider TODOs on the very next line.
                  nextCommentLocation.lineNumber == line++ + 1 &&
                  // Only consider comment tokens starting at the same column.
                  nextCommentLocation.columnNumber ==
                      commentLocation.columnNumber &&
                  // And indented more than the original 'todo' text.
                  columnOfFirstNoneMarkerOrWhitespace == column + 1 &&
                  // And not their own todos.
                  !TodoCode.TODO_REGEX.hasMatch(nextComment.lexeme);
          if (!isContinuation) {
            break;
          }

          // Track the end of the continuation for the diagnostic range.
          end = nextComment.end;
          final lexemeTextOffset = columnOfFirstNoneMarkerOrWhitespace -
              nextCommentLocation.columnNumber;
          final continuationText =
              nextComment.lexeme.substring(lexemeTextOffset).trimRight();
          todoText = '$todoText $continuationText';
          nextComment = nextComment.next;
        }
      }

      _errorReporter.reportErrorForOffset(
          TodoCode.forKind(todoKind), offset, end - offset, [todoText]);
    }

    return nextComment;
  }
}
