// 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 is InterfaceType) {
        var library = context.libraryElement ?? type.element.library;
        var getter = type.lookUpGetter(lexeme, library);
        var method = type.lookUpMethod(lexeme, library);
        if (getter == null &&
            method == null &&
            !(type.element.isDartCoreFunction &&
                lexeme == MethodElement.CALL_METHOD_NAME)) {
          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';
}
