// 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/dart/data_driven.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/change.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
import 'package:analyzer_plugin/utilities/range_factory.dart';

/// The data related to a parameter that has been renamed.
class RenameParameter extends Change<_Data> {
  /// The old name of the parameter.
  final String oldName;

  /// The new name of the parameter.
  final String newName;

  /// Initialize a newly created transform to describe a renaming of a parameter
  /// from the [oldName] to the [newName].
  RenameParameter({required this.newName, required this.oldName});

  @override
  void apply(DartFileEditBuilder builder, DataDrivenFix fix, _Data data) {
    if (data is _InvocationData) {
      builder.addSimpleReplacement(range.node(data.nameNode), newName);
    } else if (data is _OverrideData) {
      var declaration = data.methodDeclaration;
      var parameter = declaration.parameterNamed(oldName);
      if (parameter != null) {
        var overriddenMethod = declaration.overriddenElement();
        var overriddenParameter = overriddenMethod?.parameterNamed(oldName);
        if (overriddenParameter == null) {
          // If the overridden parameter has already been removed, then just
          // rename the old parameter to have the new name.
          var identifier = parameter.identifier;
          if (identifier != null) {
            builder.addSimpleReplacement(range.node(identifier), newName);
          }
        } else {
          // If the overridden parameter still exists, then mark it as
          // deprecated (if it isn't already) and add a declaration of the new
          // parameter.
          var parameterElement = parameter.declaredElement;
          if (parameterElement != null) {
            builder.addInsertion(parameter.offset, (builder) {
              builder.writeParameter(newName,
                  isCovariant: parameterElement.isCovariant,
                  isRequiredNamed: parameterElement.isRequiredNamed,
                  type: parameterElement.type);
              builder.write(', ');
              if (!parameterElement.hasDeprecated) {
                builder.write('@deprecated ');
              }
            });
          }
        }
      }
    }
  }

  @override
  _Data validate(DataDrivenFix fix) {
    var node = fix.node;
    if (node is SimpleIdentifier) {
      var parent = node.parent;
      var grandParent = parent?.parent;
      if (node.name == oldName &&
          parent is Label &&
          grandParent is NamedExpression) {
        var invocation = grandParent.parent?.parent;
        if (invocation != null && fix.element.matches(invocation)) {
          return _InvocationData(node);
        }
      } else if (parent is MethodDeclaration) {
        return _OverrideData(parent);
      }
    }
    return const _IgnoredData();
  }
}

/// The data returned from `validate`.
abstract class _Data {
  const _Data();
}

/// The data returned when the change doesn't apply.
class _IgnoredData extends _Data {
  const _IgnoredData();
}

/// The data returned when updating an invocation site.
class _InvocationData extends _Data {
  /// The node representing the name to be replaced.
  final SimpleIdentifier nameNode;

  /// Initialize newly created data about an invocation site.
  _InvocationData(this.nameNode);
}

/// The data returned when updating an override site.
class _OverrideData extends _Data {
  /// The node representing the overriding method.
  final MethodDeclaration methodDeclaration;

  /// Initialize newly created data about an override site.
  _OverrideData(this.methodDeclaration);
}

extension on MethodDeclaration {
  /// Return the parameter of this method whose name matches the given [name],
  /// or `null` if there is no such parameter.
  FormalParameter? parameterNamed(String name) {
    final parameters = this.parameters;
    if (parameters != null) {
      for (var parameter in parameters.parameters) {
        if (parameter.declaredElement?.name == name) {
          return parameter;
        }
      }
    }
    return null;
  }

  /// Return the element that this method overrides, or `null` if this method
  /// doesn't override any inherited member.
  ExecutableElement? overriddenElement() {
    var element = declaredElement;
    if (element != null) {
      var enclosingElement = element.enclosingElement;
      if (enclosingElement is ClassElement) {
        var name = Name(enclosingElement.library.source.uri, element.name);
        return InheritanceManager3().getInherited2(enclosingElement, name);
      }
    }
    return null;
  }
}

extension on ExecutableElement {
  /// Return the parameter of this executable element whose name matches the
  /// given [name], or `null` if there is no such parameter.
  ParameterElement? parameterNamed(String name) {
    for (var parameter in parameters) {
      if (parameter.name == name) {
        return parameter;
      }
    }
    return null;
  }
}
