// 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/analysis_rule/rule_context.dart';
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, RuleContext context) {
    var visitor = _Visitor(this, context);
    registry.addCompilationUnit(this, visitor);
  }
}

class _Visitor extends SimpleAstVisitor<void> {
  final LintRule rule;
  final RuleContext 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 /* '/' */;
  }
}
