// 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:_fe_analyzer_shared/src/scanner/token.dart';
import 'package:analysis_server/src/services/completion/dart/utilities.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/dart/element/element.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
import 'package:collection/collection.dart';

class AddMissingRequiredArgument extends CorrectionProducer {
  /// The name of the parameter that was missing.
  String _missingParameterName = '';

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

  @override
  FixKind get fixKind => DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT;

  @override
  Future<void> compute(ChangeBuilder builder) async {
    InstanceCreationExpression? creation;
    Element? targetElement;
    ArgumentList? argumentList;

    if (node is SimpleIdentifier || node is ConstructorName) {
      var invocation = node.parent;
      if (invocation is MethodInvocation) {
        targetElement = invocation.methodName.staticElement;
        argumentList = invocation.argumentList;
      } else {
        creation = invocation?.thisOrAncestorOfType();
        if (creation != null) {
          targetElement = creation.constructorName.staticElement;
          argumentList = creation.argumentList;
        }
      }
    }

    final diagnostic = this.diagnostic;
    if (diagnostic == null) {
      return;
    }

    if (targetElement is ExecutableElement && argumentList != null) {
      // Format: "Missing required argument 'foo'."
      var messageParts =
          diagnostic.problemMessage.messageText(includeUrl: false).split("'");
      if (messageParts.length < 2) {
        return;
      }
      _missingParameterName = messageParts[1];

      var missingParameter = targetElement.parameters.firstWhereOrNull(
        (p) => p.name == _missingParameterName,
      );
      if (missingParameter == null) {
        return;
      }

      int offset;
      var hasTrailingComma = false;
      var insertBetweenParams = false;
      List<Expression> arguments = argumentList.arguments;
      if (arguments.isEmpty) {
        offset = argumentList.leftParenthesis.end;
      } else {
        var lastArgument = arguments.last;
        offset = lastArgument.end;
        hasTrailingComma = lastArgument.endToken.next!.type == TokenType.COMMA;

        if (lastArgument is NamedExpression &&
            flutter.isWidgetExpression(creation)) {
          if (flutter.isChildArgument(lastArgument) ||
              flutter.isChildrenArgument(lastArgument)) {
            offset = lastArgument.offset;
            hasTrailingComma = true;
            insertBetweenParams = true;
          }
        }
      }

      var defaultValue = getDefaultStringParameterValue(missingParameter,
          withNullability: libraryElement.isNonNullableByDefault &&
              (missingParameter.library?.isNonNullableByDefault ?? false));

      await builder.addDartFileEdit(file, (builder) {
        builder.addInsertion(offset, (builder) {
          if (arguments.isNotEmpty && !insertBetweenParams) {
            builder.write(', ');
          }

          builder.write('$_missingParameterName: ');

          // Use defaultValue.cursorPosition if it's not null.
          if (defaultValue != null) {
            var cursorPosition = defaultValue.cursorPosition;
            if (cursorPosition != null) {
              builder.write(defaultValue.text.substring(0, cursorPosition));
              builder.selectHere();
              builder.write(defaultValue.text.substring(cursorPosition));
            } else {
              builder.addSimpleLinkedEdit('VALUE', defaultValue.text);
            }
          } else {
            builder.addSimpleLinkedEdit('VALUE', 'null');
          }

          if (flutter.isWidgetExpression(creation)) {
            // Insert a trailing comma after Flutter instance creation params.
            if (!hasTrailingComma) {
              builder.write(',');
            } else if (insertBetweenParams) {
              builder.writeln(',');

              // Insert indent before the child: or children: param.
              var indent = utils.getLinePrefix(offset);
              builder.write(indent);
            }
          }
        });
      });
    }
  }

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