// Copyright (c) 2025, 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/analysis_rule.dart';
import 'package:analyzer/analysis_rule/rule_context.dart';
import 'package:analyzer/analysis_rule/rule_visitor_registry.dart';
import 'package:analyzer/dart/analysis/features.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/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/error.dart';

import '../analyzer.dart';
import '../diagnostic.dart' as diag;

const _desc = 'Avoid unnecessary member names in variable patterns.';

class SimplifyVariablePattern extends AnalysisRule {
  new() : super(name: LintNames.simplify_variable_pattern, description: _desc);

  @override
  DiagnosticCode get diagnosticCode => diag.simplifyVariablePattern;

  @override
  void registerNodeProcessors(
    RuleVisitorRegistry registry,
    RuleContext context,
  ) {
    if (!context.isFeatureEnabled(Feature.patterns)) return;
    var visitor = _Visitor(this, context);
    registry.addPatternField(this, visitor);
  }
}

class _Visitor(final AnalysisRule rule, final RuleContext context)
    extends SimpleAstVisitor<void> {
  @override
  void visitPatternField(PatternField node) {
    var pattern = node.pattern.unParenthesized;
    if (pattern is! DeclaredVariablePattern) return;
    if (node.name?.name case Token(:var isSynthetic, :var lexeme) && var name
        when !isSynthetic && pattern.name.lexeme == lexeme) {
      // Make sure the name exists
      if (node.parent case RecordPattern(:var matchedValueType)) {
        _reportIfNeeded(
          name,
          matchedValueType,
          lexeme: lexeme,
          accessor: _accessor(node),
        );
      } else if (node.parent case ObjectPattern(
        type: NamedType(:var element?, :var type),
      )) {
        while (element is TypeAliasElement || element is TypeParameterElement) {
          if (element case TypeAliasElement(
            aliasedType: DartType(element: var aliasedElement) &&
                var aliasedType,
          )) {
            type = aliasedType;
            if (aliasedElement == null) {
              break;
            }
            element = aliasedElement;
          } else if (element is TypeParameterElement) {
            type = element.bound ?? context.typeProvider.objectQuestionType;
            var boundedElement = type.element;
            if (boundedElement == null) {
              break;
            }
            element = boundedElement;
          }
        }
        _reportIfNeeded(name, type, lexeme: lexeme, accessor: _accessor(node));
      }
    }
    super.visitPatternField(node);
  }

  String _accessor(PatternField field) => switch (field.parent) {
    ObjectPattern() when field.element is MethodElement => 'method',
    ObjectPattern() when field.element is GetterElement => 'getter',
    _ => 'field',
  };

  void _reportIfNeeded(
    Token name,
    DartType? type, {
    required String lexeme,
    required String accessor,
  }) {
    if (type is! DynamicType) {
      if (type?.element case InstanceElement element) {
        var methods = element.methods.map((e) => e.name).toList();
        if (element.isDartCoreFunction) {
          methods.add(MethodElement.CALL_METHOD_NAME);
        }
        if (!element.getters.map((e) => e.name).contains(lexeme) &&
            !methods.contains(lexeme)) {
          return;
        }
      } else if (type case RecordType record) {
        if (!record.namedFields.map((field) => field.name).contains(lexeme)) {
          return;
        }
      } else if (type is FunctionType) {
        if (name.lexeme != MethodElement.CALL_METHOD_NAME) {
          return;
        }
      } else {
        return;
      }
    }
    rule.reportAtToken(name, arguments: [lexeme, accessor]);
  }
}

extension on InstanceElement {
  bool get isDartCoreFunction => library.isDartCore && name == 'Function';
}
