// Copyright (c) 2024, 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/visitor.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/src/ignore_comments/ignore_info.dart' // ignore: implementation_imports
    show
        CommentTokenExtension,
        CompilationUnitExtension,
        IgnoredDiagnosticComment;
import 'package:analyzer/src/utilities/extensions/string.dart' // ignore: implementation_imports
    show IntExtension;

import '../analyzer.dart';

const _desc = r'Document ignore comments.';

class DocumentIgnores extends LintRule {
  DocumentIgnores()
    : super(name: LintNames.document_ignores, description: _desc);

  @override
  DiagnosticCode get diagnosticCode => LinterLintCode.document_ignores;

  @override
  void registerNodeProcessors(
    NodeLintRegistry registry,
    LinterContext context,
  ) {
    var visitor = _Visitor(this, context);
    registry.addCompilationUnit(this, visitor);
  }
}

class _Visitor extends SimpleAstVisitor<void> {
  final LintRule rule;
  final LinterContext context;

  _Visitor(this.rule, this.context);

  @override
  void visitCompilationUnit(CompilationUnit node) {
    assert(context.currentUnit?.unit == node);
    var content = context.currentUnit?.content;
    for (var comment in node.ignoreComments) {
      var ignoredElements = comment.ignoredElements;
      if (ignoredElements.isEmpty) {
        continue;
      }
      if (ignoredElements.last is IgnoredDiagnosticComment) {
        // Some trailing text in `comment` documents this/these ignore(s).
        continue;
      }

      var ignoreCommentLine =
          node.lineInfo.getLocation(comment.offset).lineNumber;
      if (ignoreCommentLine > 1) {
        // Only look at the line above if the ignore comment line is not the
        // first line.
        var previousLineOffset = node.lineInfo.getOffsetOfLine(
          ignoreCommentLine - 2,
        );
        if (content != null &&
            _startsWithEndOfLineComment(content, previousLineOffset)) {
          // A preceding comment, which may be attached to a different token,
          // documents this/these ignore(s). For example in:
          //
          // ```dart
          // // Text.
          // int x = 0; // ignore: unused_element
          // ```
          continue;
        }
      }

      rule.reportAtToken(comment);
    }
  }

  /// Returns whether [content] at [offset_] represents starts with optional
  /// whitespace and then an end-of-line comment (two slashes).
  bool _startsWithEndOfLineComment(String content, int offset_) {
    var offset = offset_;
    var length = content.length;
    while (offset < length) {
      if (!content.codeUnitAt(offset).isSpace) break;
      offset++;
    }
    if (offset + 1 >= length) return false;
    return content.codeUnitAt(offset) == 0x2F /* '/' */ &&
        content.codeUnitAt(offset + 1) == 0x2F /* '/' */;
  }
}
