// Copyright (c) 2020, 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 'dart:collection';

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/error/hint_codes.dart';

class MustCallSuperVerifier {
  final ErrorReporter _errorReporter;

  MustCallSuperVerifier(this._errorReporter);

  void checkMethodDeclaration(MethodDeclaration node) {
    if (node.isStatic || node.isAbstract) {
      return;
    }
    var element = node.declaredElement!;
    var overridden = _findOverriddenMemberWithMustCallSuper(element);
    if (overridden == null) {
      return;
    }

    if (element is MethodElement && _hasConcreteSuperMethod(element)) {
      _verifySuperIsCalled(
          node, overridden.name, overridden.enclosingElement.name);
      return;
    }

    var enclosingElement = element.enclosingElement as ClassElement;
    if (element is PropertyAccessorElement && element.isGetter) {
      var inheritedConcreteGetter = enclosingElement
          .lookUpInheritedConcreteGetter(element.name, element.library);
      if (inheritedConcreteGetter != null) {
        _verifySuperIsCalled(
            node, overridden.name, overridden.enclosingElement.name);
      }
      return;
    }

    if (element is PropertyAccessorElement && element.isSetter) {
      var inheritedConcreteSetter = enclosingElement
          .lookUpInheritedConcreteSetter(element.name, element.library);
      if (inheritedConcreteSetter != null) {
        var name = overridden.name;
        // For a setter, give the name without the trailing '=' to the verifier,
        // in order to check against property access.
        if (name.endsWith('=')) {
          name = name.substring(0, name.length - 1);
        }
        _verifySuperIsCalled(node, name, overridden.enclosingElement.name);
      }
    }
  }

  /// Find a method which is overridden by [node] and which is annotated with
  /// `@mustCallSuper`.
  ///
  /// As per the definition of `mustCallSuper` [1], every method which overrides
  /// a method annotated with `@mustCallSuper` is implicitly annotated with
  /// `@mustCallSuper`.
  ///
  /// [1]: https://pub.dev/documentation/meta/latest/meta/mustCallSuper-constant.html
  ExecutableElement? _findOverriddenMemberWithMustCallSuper(
      ExecutableElement element) {
    //Element member = node.declaredElement;
    if (element.enclosingElement is! ClassElement) {
      return null;
    }
    var classElement = element.enclosingElement as ClassElement;
    String name = element.name;

    // Walk up the type hierarchy from [classElement], ignoring direct
    // interfaces.
    Queue<ClassElement?> superclasses =
        Queue.of(classElement.mixins.map((i) => i.element))
          ..addAll(classElement.superclassConstraints.map((i) => i.element))
          ..add(classElement.supertype?.element);
    var visitedClasses = <ClassElement>{};
    while (superclasses.isNotEmpty) {
      var ancestor = superclasses.removeFirst();
      if (ancestor == null || !visitedClasses.add(ancestor)) {
        continue;
      }
      var member = ancestor.getMethod(name) ??
          ancestor.getGetter(name) ??
          ancestor.getSetter(name);
      if (member is MethodElement && member.hasMustCallSuper) {
        return member;
      }
      if (member is PropertyAccessorElement && member.hasMustCallSuper) {
        // TODO(srawlins): What about a field annotated with `@mustCallSuper`?
        // This might seem a legitimate case, but is not called out in the
        // documentation of [mustCallSuper].
        return member;
      }
      superclasses
        ..addAll(ancestor.mixins.map((i) => i.element))
        ..addAll(ancestor.superclassConstraints.map((i) => i.element))
        ..add(ancestor.supertype?.element);
    }
    return null;
  }

  /// Returns whether [node] overrides a concrete method.
  bool _hasConcreteSuperMethod(ExecutableElement element) {
    var classElement = element.enclosingElement as ClassElement;
    String name = element.name;

    bool isConcrete(ClassElement element) =>
        element.lookUpConcreteMethod(name, element.library) != null;

    if (classElement.mixins.map((i) => i.element).any(isConcrete)) {
      return true;
    }
    if (classElement.superclassConstraints
        .map((i) => i.element)
        .any(isConcrete)) {
      return true;
    }

    var supertype = classElement.supertype;
    if (supertype != null && isConcrete(supertype.element)) {
      return true;
    }

    return false;
  }

  void _verifySuperIsCalled(MethodDeclaration node, String methodName,
      String? overriddenEnclosingName) {
    _SuperCallVerifier verifier = _SuperCallVerifier(methodName);
    node.accept(verifier);
    if (!verifier.superIsCalled) {
      // Overridable elements are always enclosed in named elements, so it is
      // safe to assume [overriddenEnclosingName] is non-`null`.
      _errorReporter.reportErrorForNode(
          HintCode.MUST_CALL_SUPER, node.name, [overriddenEnclosingName!]);
    }
    return;
  }
}

/// Recursively visits an AST, looking for method invocations.
class _SuperCallVerifier extends RecursiveAstVisitor<void> {
  bool superIsCalled = false;

  final String name;

  _SuperCallVerifier(this.name);

  @override
  void visitAssignmentExpression(AssignmentExpression node) {
    var lhs = node.leftHandSide;
    if (lhs is PropertyAccess) {
      if (lhs.target is SuperExpression && lhs.propertyName.name == name) {
        superIsCalled = true;
        return;
      }
    }
    super.visitAssignmentExpression(node);
  }

  @override
  void visitBinaryExpression(BinaryExpression node) {
    if (node.leftOperand is SuperExpression && node.operator.lexeme == name) {
      superIsCalled = true;
      return;
    }
    super.visitBinaryExpression(node);
  }

  @override
  void visitMethodInvocation(MethodInvocation node) {
    if (node.target is SuperExpression && node.methodName.name == name) {
      superIsCalled = true;
      return;
    }
    super.visitMethodInvocation(node);
  }

  @override
  void visitPropertyAccess(PropertyAccess node) {
    if (node.target is SuperExpression && node.propertyName.name == name) {
      superIsCalled = true;
      return;
    }
    super.visitPropertyAccess(node);
  }
}
