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

/// The addition of a new parameter.
class AddParameter extends ParameterModification {
  /// The index of the parameter in the parameter list after the modifications
  /// have been applied.
  final int index;

  /// The name of the parameter that was added.
  final String name;

  /// A flag indicating whether the parameter is a required parameter.
  final bool isRequired;

  /// A flag indicating whether the parameter is a positional parameter.
  final bool isPositional;

  /// The code template used to compute the value of the new argument in
  /// invocations of the function, or `null` if the parameter is optional and no
  /// argument needs to be added. The only time an argument needs to be added
  /// for an optional parameter is if the parameter is positional and there are
  /// pre-existing optional positional parameters after the ones being added.
  final CodeTemplate argumentValue;

  /// Initialize a newly created parameter modification to represent the
  /// addition of a parameter. If provided, the [argumentValue] will be used as
  /// the value of the new argument in invocations of the function.
  AddParameter(this.index, this.name, this.isRequired, this.isPositional,
      this.argumentValue)
      : assert(index >= 0),
        assert(name != null);
}

/// The data related to an executable element whose parameters have been
/// modified.
class ModifyParameters extends Change<_Data> {
  /// A list of the modifications being made.
  final List<ParameterModification> modifications;

  /// Initialize a newly created transform to modifications to the parameter
  /// list of a function.
  ModifyParameters({@required this.modifications})
      : assert(modifications != null),
        assert(modifications.isNotEmpty);

  @override
  void apply(DartFileEditBuilder builder, DataDrivenFix fix, _Data data) {
    var argumentList = data.argumentList;
    var arguments = argumentList.arguments;
    var argumentCount = arguments.length;
    var templateContext = TemplateContext(argumentList.parent, fix.utils);

    var indexToNewArgumentMap = <int, AddParameter>{};
    var argumentsToInsert = <int>[];
    var argumentsToDelete = <int>[];
    var remainingArguments = [for (var i = 0; i < argumentCount; i++) i];
    for (var modification in modifications) {
      if (modification is AddParameter) {
        var index = modification.index;
        indexToNewArgumentMap[index] = modification;
        if (modification.isPositional || modification.isRequired) {
          argumentsToInsert.add(index);
        } else {
          var requiredIfCondition =
              modification.argumentValue?.requiredIfCondition;
          if (requiredIfCondition != null &&
              requiredIfCondition.evaluateIn(templateContext)) {
            argumentsToInsert.add(index);
          }
        }
      } else if (modification is RemoveParameter) {
        var argument = modification.parameter.argumentFrom(argumentList);
        // If there is no argument corresponding to the parameter then we assume
        // that the parameter was optional (and absent) and don't try to remove
        // it.
        if (argument != null) {
          var index = arguments.indexOf(_realArgument(argument));
          argumentsToDelete.add(index);
          remainingArguments.remove(index);
        }
      }
    }
    argumentsToInsert.sort();

    /// Write to the [builder] the argument associated with a single
    /// [parameter].
    void writeArgument(DartEditBuilder builder, AddParameter parameter) {
      if (!parameter.isPositional) {
        builder.write(parameter.name);
        builder.write(': ');
      }
      parameter.argumentValue.writeOn(builder, templateContext);
    }

    var insertionRanges = argumentsToInsert.contiguousSubRanges.toList();
    var deletionRanges = argumentsToDelete.contiguousSubRanges.toList();
    if (insertionRanges.isNotEmpty) {
      /// Write to the [builder] the new arguments in the [insertionRange]. If
      /// [needsInitialComma] is `true` then we need to write a comma before the
      /// first of the new arguments.
      void writeInsertionRange(DartEditBuilder builder,
          _IndexRange insertionRange, bool needsInitialComma) {
        var needsComma = needsInitialComma;
        for (var argumentIndex = insertionRange.lower;
            argumentIndex <= insertionRange.upper;
            argumentIndex++) {
          if (needsComma) {
            builder.write(', ');
          } else {
            needsComma = true;
          }
          var parameter = indexToNewArgumentMap[argumentIndex];
          writeArgument(builder, parameter);
        }
      }

      var nextRemaining = 0;
      var nextInsertionRange = 0;
      var insertionCount = 0;
      while (nextRemaining < remainingArguments.length &&
          nextInsertionRange < insertionRanges.length) {
        var remainingIndex = remainingArguments[nextRemaining];
        var insertionRange = insertionRanges[nextInsertionRange];
        var insertionIndex = insertionRange.lower;
        if (insertionIndex <= remainingIndex + insertionCount) {
          // There are arguments that need to be inserted before the next
          // remaining argument.
          var deletionRange =
              _rangeContaining(deletionRanges, insertionIndex - 1);
          if (deletionRange == null) {
            // The insertion range doesn't overlap a deletion range, so insert
            // the added arguments before the argument whose index is
            // `remainingIndex`.
            int offset;
            var needsInitialComma = false;
            if (insertionIndex > 0) {
              offset = arguments[remainingIndex - 1].end;
              needsInitialComma = true;
            } else {
              offset = arguments[remainingIndex].offset;
            }
            builder.addInsertion(offset, (builder) {
              writeInsertionRange(builder, insertionRange, needsInitialComma);
              if (insertionIndex == 0) {
                builder.write(', ');
              }
            });
          } else {
            // The insertion range overlaps a deletion range, so replace the
            // arguments in the deletion range with the arguments in the
            // insertion range.
            var replacementRange = range.argumentRange(
                argumentList, deletionRange.lower, deletionRange.upper, false);
            builder.addReplacement(replacementRange, (builder) {
              writeInsertionRange(builder, insertionRange, false);
            });
            deletionRanges.remove(deletionRange);
          }
          insertionCount += insertionRange.count;
          nextInsertionRange++;
        } else {
          // There are no arguments that need to be inserted before the next
          // remaining argument, so just move past the next remaining argument.
          nextRemaining++;
        }
      }
      // The remaining insertion ranges might include new required arguments
      // that need to be inserted after the last argument.
      var offset = arguments.isEmpty
          ? argumentList.leftParenthesis.end
          : arguments[arguments.length - 1].end;
      while (nextInsertionRange < insertionRanges.length) {
        var insertionRange = insertionRanges[nextInsertionRange];
        var lower = insertionRange.lower;
        var upper = insertionRange.upper;
        var parameter = indexToNewArgumentMap[upper];
        while (upper >= lower &&
            (parameter.isPositional && !parameter.isRequired)) {
          upper--;
        }
        if (upper >= lower) {
          builder.addInsertion(offset, (builder) {
            writeInsertionRange(builder, _IndexRange(lower, upper),
                nextRemaining > 0 || insertionCount > 0);
          });
        }
        nextInsertionRange++;
      }
    }
    //
    // The remaining deletion ranges are now ready to be removed.
    //
    for (var subRange in deletionRanges) {
      builder.addDeletion(range.argumentRange(
          argumentList, subRange.lower, subRange.upper, true));
    }
  }

  @override
  _Data validate(DataDrivenFix fix) {
    var node = fix.node;
    var parent = node.parent;
    if (parent is InvocationExpression) {
      var argumentList = parent.argumentList;
      return _Data(argumentList);
    } else if (parent is Label) {
      var argumentList = parent.parent.parent;
      if (argumentList is ArgumentList) {
        return _Data(argumentList);
      }
    } else if (parent?.parent is InvocationExpression) {
      var argumentList = (parent.parent as InvocationExpression).argumentList;
      return _Data(argumentList);
    } else if (parent is TypeName &&
        parent.parent is ConstructorName &&
        parent.parent.parent is InstanceCreationExpression) {
      var argumentList =
          (parent.parent.parent as InstanceCreationExpression).argumentList;
      return _Data(argumentList);
    }
    return null;
  }

  /// Return the range from the list of [ranges] that contains the given
  /// [index], or `null` if there is no such range.
  _IndexRange _rangeContaining(List<_IndexRange> ranges, int index) {
    for (var range in ranges) {
      if (index >= range.lower && index <= range.upper) {
        return range;
      }
    }
    return null;
  }

  /// Return the element of the argument list whose value is the given
  /// [argument]. If the argument is the child of a named expression, then that
  /// will be the named expression, otherwise it will be the argument itself.
  Expression _realArgument(Expression argument) =>
      argument.parent is NamedExpression ? argument.parent : argument;
}

/// A modification related to a parameter.
abstract class ParameterModification {}

/// The removal of an existing parameter.
class RemoveParameter extends ParameterModification {
  /// The parameter that was removed.
  final ParameterReference parameter;

  /// Initialize a newly created parameter modification to represent the removal
  /// of an existing [parameter].
  RemoveParameter(this.parameter) : assert(parameter != null);
}

/// The data returned when updating an invocation site.
class _Data {
  /// The argument list to be updated.
  final ArgumentList argumentList;

  /// Initialize a newly created data object with the data needed to update an
  /// invocation site.
  _Data(this.argumentList);
}

/// A range of indexes within a list.
class _IndexRange {
  /// The index of the first element in the range.
  final int lower;

  /// The index of the last element in the range. This will be the same as the
  /// [lower] if there is a single element in the range.
  final int upper;

  /// Initialize a newly created range.
  _IndexRange(this.lower, this.upper);

  /// Return the number of indices in this range.
  int get count => upper - lower + 1;

  @override
  String toString() => '[$lower..$upper]';
}

extension on List<int> {
  Iterable<_IndexRange> get contiguousSubRanges sync* {
    if (isEmpty) {
      return;
    }
    var lower = this[0];
    var previous = lower;
    var index = 1;
    while (index < length) {
      var current = this[index];
      if (current == previous + 1) {
        previous = current;
      } else {
        yield _IndexRange(lower, previous);
        lower = previous = current;
      }
      index++;
    }
    yield _IndexRange(lower, previous);
  }
}
