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

class ReplaceWithVar extends CorrectionProducer {
  @override
  AssistKind get assistKind => DartAssistKind.REPLACE_WITH_VAR;

  @override
  bool get canBeAppliedInBulk => true;

  @override
  bool get canBeAppliedToFile => true;

  @override
  FixKind get fixKind => DartFixKind.REPLACE_WITH_VAR;

  @override
  FixKind get multiFixKind => DartFixKind.REPLACE_WITH_VAR_MULTI;

  @override
  Future<void> compute(ChangeBuilder builder) async {
    var type = _findType(node);
    if (type == null) {
      return;
    }
    // TODO(brianwilkerson) Optimize this by removing the duplication between
    //  [_canReplaceWithVar] and the rest of this method.
    if (!_canReplaceWithVar()) {
      return;
    }
    var parent = type.parent;
    var grandparent = parent?.parent;
    if (parent is VariableDeclarationList &&
        (grandparent is VariableDeclarationStatement ||
            grandparent is ForPartsWithDeclarations)) {
      var variables = parent.variables;
      if (variables.length != 1) {
        return;
      }
      var initializer = variables[0].initializer;
      String? typeArgumentsText;
      int? typeArgumentsOffset;
      if (type is NamedType) {
        var typeArguments = type.typeArguments;
        if (typeArguments != null) {
          if (initializer is CascadeExpression) {
            initializer = initializer.target;
          }
          if (initializer is TypedLiteral) {
            if (initializer.typeArguments == null) {
              typeArgumentsText = utils.getNodeText(typeArguments);
              if (initializer is ListLiteral) {
                typeArgumentsOffset = initializer.leftBracket.offset;
              } else if (initializer is SetOrMapLiteral) {
                typeArgumentsOffset = initializer.leftBracket.offset;
              }
            }
          } else if (initializer is InstanceCreationExpression) {
            if (initializer.constructorName.type2.typeArguments == null) {
              typeArgumentsText = utils.getNodeText(typeArguments);
              typeArgumentsOffset = initializer.constructorName.type2.end;
            }
          }
        }
      }
      if (initializer is SetOrMapLiteral &&
          initializer.typeArguments == null &&
          typeArgumentsText == null) {
        // TODO(brianwilkerson) This is to prevent the fix from converting a
        //  valid map or set literal into an ambiguous literal. We could apply
        //  this in more places by examining the elements of the collection.
        return;
      }
      await builder.addDartFileEdit(file, (builder) {
        if (parent.isConst || parent.isFinal) {
          builder.addDeletion(range.startStart(type, variables[0]));
        } else {
          builder.addSimpleReplacement(range.node(type), 'var');
        }
        if (typeArgumentsText != null && typeArgumentsOffset != null) {
          builder.addSimpleInsertion(typeArgumentsOffset, typeArgumentsText);
        }
      });
    } else if (parent is DeclaredIdentifier &&
        grandparent is ForEachPartsWithDeclaration) {
      String? typeArgumentsText;
      int? typeArgumentsOffset;
      if (type is NamedType) {
        var typeArguments = type.typeArguments;
        if (typeArguments != null) {
          var iterable = grandparent.iterable;
          if (iterable is TypedLiteral && iterable.typeArguments == null) {
            typeArgumentsText = utils.getNodeText(typeArguments);
            typeArgumentsOffset = iterable.offset;
          }
        }
      }
      await builder.addDartFileEdit(file, (builder) {
        if (parent.isConst || parent.isFinal) {
          builder.addDeletion(range.startStart(type, parent.identifier));
        } else {
          builder.addSimpleReplacement(range.node(type), 'var');
        }
        if (typeArgumentsText != null && typeArgumentsOffset != null) {
          builder.addSimpleInsertion(typeArgumentsOffset, typeArgumentsText);
        }
      });
    }
  }

  /// Return `true` if the type in the [node] can be replaced with `var`.
  bool _canConvertVariableDeclarationList(VariableDeclarationList node) {
    final staticType = node.type?.type;
    if (staticType == null || staticType.isDynamic) {
      return false;
    }
    for (final child in node.variables) {
      var initializer = child.initializer;
      if (initializer == null || initializer.staticType != staticType) {
        return false;
      }
    }
    return true;
  }

  /// Return `true` if the [node] can be replaced with `var`.
  bool _canReplaceWithVar() {
    var parent = node.parent;
    while (parent != null) {
      if (parent is VariableDeclarationStatement) {
        return _canConvertVariableDeclarationList(parent.variables);
      } else if (parent is ForPartsWithDeclarations) {
        return _canConvertVariableDeclarationList(parent.variables);
      } else if (parent is ForEachPartsWithDeclaration) {
        var loopVariableType = parent.loopVariable.type;
        var staticType = loopVariableType?.type;
        if (staticType == null || staticType.isDynamic) {
          return false;
        }
        final iterableType = parent.iterable.typeOrThrow;
        var instantiatedType =
            iterableType.asInstanceOf(typeProvider.iterableElement);
        if (instantiatedType?.typeArguments.first == staticType) {
          return true;
        }
        return false;
      }
      parent = parent.parent;
    }
    return false;
  }

  /// Using the [node] as a starting point, return the type annotation that is
  /// to be replaced, or `null` if there is no type annotation.
  TypeAnnotation? _findType(AstNode node) {
    if (node is VariableDeclarationList) {
      return node.type;
    }
    return node.thisOrAncestorOfType<TypeAnnotation>();
  }

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