// 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/abstract_producer.dart';
import 'package:analysis_server/src/services/correction/executable_parameters.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/services/correction/levenshtein.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
import 'package:analyzer_plugin/utilities/range_factory.dart';

class ChangeArgumentName extends MultiCorrectionProducer {
  static const maxDistance = 4;

  @override
  Iterable<CorrectionProducer> get producers sync* {
    var names = _getNamedParameterNames();
    if (names == null || names.isEmpty) {
      return;
    }
    SimpleIdentifier argumentName = node;
    var invalidName = argumentName.name;
    for (var proposedName in names) {
      var distance = _computeDistance(invalidName, proposedName);
      if (distance <= maxDistance) {
        // TODO(brianwilkerson) Create a way to use the distance as part of the
        //  computation of the priority (so that closer names sort first).
        yield _ChangeName(argumentName, proposedName);
      }
    }
  }

  int _computeDistance(String current, String proposal) {
    if ((current == 'child' && proposal == 'children') ||
        (current == 'children' && proposal == 'child')) {
      // Special case handling for 'child' and 'children' is unnecessary if
      // `maxDistance >= 3`, but is included to prevent regression in case the
      // value is changed to improve results.
      return 1;
    }
    return levenshtein(current, proposal, maxDistance, caseSensitive: false);
  }

  List<String> _getNamedParameterNames() {
    var namedExpression = node?.parent?.parent;
    if (node is SimpleIdentifier &&
        namedExpression is NamedExpression &&
        namedExpression.name == node.parent &&
        namedExpression.parent is ArgumentList) {
      var parameters = ExecutableParameters(
        sessionHelper,
        namedExpression.parent.parent,
      );
      return parameters?.namedNames;
    }
    return null;
  }

  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
  static ChangeArgumentName newInstance() => ChangeArgumentName();
}

/// A correction processor that can make one of the possible change computed by
/// the [ChangeArgumentName] producer.
class _ChangeName extends CorrectionProducer {
  /// The name of the argument being changed.
  final SimpleIdentifier argumentName;

  /// The name to which the argument name will be changed.
  final String proposedName;

  _ChangeName(this.argumentName, this.proposedName);

  @override
  List<Object> get fixArguments => [proposedName];

  @override
  FixKind get fixKind => DartFixKind.CHANGE_ARGUMENT_NAME;

  @override
  Future<void> compute(DartChangeBuilder builder) async {
    await builder.addFileEdit(file, (builder) {
      builder.addSimpleReplacement(range.node(argumentName), proposedName);
    });
  }
}
