// Copyright (c) 2023, 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/dart/element/element2.dart';

import '../analyzer.dart';

const _desc = r"Don't implicitly reopen classes.";

class ImplicitReopen extends LintRule {
  ImplicitReopen()
      : super(
          name: LintNames.implicit_reopen,
          description: _desc,
          state: const State.experimental(),
        );

  @override
  LintCode get lintCode => LinterLintCode.implicit_reopen;

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

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

  _Visitor(this.rule);

  void checkElement(InterfaceElement2? element, NamedCompilationUnitMember node,
      {required String type}) {
    if (element is! ClassElement2) return;
    if (element.metadata2.hasReopen) return;
    if (element.isSealed) return;
    if (element.isMixinClass) return;

    var library = element.library2;
    var supertype = element.supertype?.element3;
    if (supertype is! ClassElement2) return;
    if (supertype.library2 != library) return;

    if (element.isBase) {
      if (supertype.isFinal) {
        reportLint(node,
            target: element, other: supertype, reason: 'final', type: type);
        return;
      } else if (supertype.isInterface) {
        reportLint(node,
            target: element, other: supertype, reason: 'interface', type: type);
        return;
      }
    } else if (element.hasNoModifiers) {
      if (supertype.isInterface) {
        reportLint(node,
            target: element, other: supertype, reason: 'interface', type: type);
        return;
      }
    }
  }

  void reportLint(
    NamedCompilationUnitMember member, {
    required String type,
    required InterfaceElement2 target,
    required InterfaceElement2 other,
    required String reason,
  }) {
    var targetName = target.name3;
    var otherName = other.name3;
    if (targetName != null && otherName != null) {
      rule.reportLintForToken(
        member.name,
        arguments: [type, targetName, otherName, reason],
      );
    }
  }

  @override
  void visitClassDeclaration(ClassDeclaration node) {
    checkElement(node.declaredFragment?.element, node, type: 'class');
  }

  @override
  visitClassTypeAlias(ClassTypeAlias node) {
    checkElement(node.declaredFragment?.element, node, type: 'class');
  }
}

extension on ClassElement2 {
  bool get hasNoModifiers => !isInterface && !isBase && !isSealed && !isFinal;
}
