// 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 'package:analysis_server/src/services/correction/assist.dart';
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analyzer/dart/ast/ast.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_plugin/utilities/assist/assist.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
import 'package:analyzer_plugin/utilities/range_factory.dart';

class ConvertClassToMixin extends CorrectionProducer {
  @override
  AssistKind get assistKind => DartAssistKind.CONVERT_CLASS_TO_MIXIN;

  @override
  Future<void> compute(ChangeBuilder builder) async {
    var classDeclaration = node.thisOrAncestorOfType<ClassDeclaration>();
    if (classDeclaration == null) {
      return;
    }
    if (selectionOffset > classDeclaration.name2.end ||
        selectionEnd < classDeclaration.classKeyword.offset) {
      return;
    }
    if (classDeclaration.members
        .any((member) => member is ConstructorDeclaration)) {
      return;
    }
    var finder = _SuperclassReferenceFinder();
    classDeclaration.accept(finder);
    var referencedClasses = finder.referencedClasses;
    var superclassConstraints = <InterfaceType>[];
    var interfaces = <InterfaceType>[];

    var classElement = classDeclaration.declaredElement!;
    for (var type in classElement.mixins) {
      if (referencedClasses.contains(type.element2)) {
        superclassConstraints.add(type);
      } else {
        interfaces.add(type);
      }
    }

    var superType = classElement.supertype;
    if (classDeclaration.extendsClause != null && superType != null) {
      if (referencedClasses.length > superclassConstraints.length) {
        superclassConstraints.insert(0, superType);
      } else {
        interfaces.insert(0, superType);
      }
    }
    interfaces.addAll(classElement.interfaces);

    await builder.addDartFileEdit(file, (builder) {
      builder.addReplacement(
          range.startStart(
              classDeclaration.abstractKeyword ?? classDeclaration.classKeyword,
              classDeclaration.leftBracket), (builder) {
        builder.write('mixin ');
        builder.write(classDeclaration.name2.lexeme);
        builder.writeTypeParameters(classElement.typeParameters);
        builder.writeTypes(superclassConstraints, prefix: ' on ');
        builder.writeTypes(interfaces, prefix: ' implements ');
        builder.write(' ');
      });
    });
  }
}

/// A visitor used to find all of the classes that define members referenced via
/// `super`.
class _SuperclassReferenceFinder extends RecursiveAstVisitor<void> {
  final List<ClassElement> referencedClasses = <ClassElement>[];

  _SuperclassReferenceFinder();

  @override
  void visitSuperExpression(SuperExpression node) {
    var parent = node.parent;
    if (parent is BinaryExpression) {
      _addElement(parent.staticElement);
    } else if (parent is IndexExpression) {
      _addElement(parent.staticElement);
    } else if (parent is MethodInvocation) {
      _addIdentifier(parent.methodName);
    } else if (parent is PrefixedIdentifier) {
      _addIdentifier(parent.identifier);
    } else if (parent is PropertyAccess) {
      _addIdentifier(parent.propertyName);
    }
    return super.visitSuperExpression(node);
  }

  void _addElement(Element? element) {
    if (element is ExecutableElement) {
      var enclosingElement = element.enclosingElement3;
      if (enclosingElement is ClassElement) {
        referencedClasses.add(enclosingElement);
      }
    }
  }

  void _addIdentifier(SimpleIdentifier identifier) {
    _addElement(identifier.staticElement);
  }
}
