// Copyright (c) 2019, 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/lsp_protocol/protocol_generated.dart';
import 'package:analysis_server/src/lsp/constants.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../tool/lsp_spec/matchers.dart';
import 'server_abstract.dart';

void main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(RenameTest);
  });
}

@reflectiveTest
class RenameTest extends AbstractLspAnalysisServerTest {
  Future<void> test_prepare_class() {
    const content = '''
    class MyClass {}
    final a = new [[My^Class]]();
    ''';

    return _test_prepare(content, 'MyClass');
  }

  Future<void> test_prepare_classNewKeyword() async {
    const content = '''
    class MyClass {}
    final a = n^ew [[MyClass]]();
    ''';

    return _test_prepare(content, 'MyClass');
  }

  Future<void> test_prepare_importPrefix() async {
    const content = '''
    import 'dart:async' as [[myPr^efix]];
    ''';

    return _test_prepare(content, 'myPrefix');
  }

  Future<void> test_prepare_importWithoutPrefix() async {
    const content = '''
    imp[[^]]ort 'dart:async';
    ''';

    return _test_prepare(content, '');
  }

  Future<void> test_prepare_importWithPrefix() async {
    const content = '''
    imp^ort 'dart:async' as [[myPrefix]];
    ''';

    return _test_prepare(content, 'myPrefix');
  }

  Future<void> test_prepare_invalidRenameLocation() async {
    const content = '''
    main() {
      // comm^ent
    }
    ''';

    return _test_prepare(content, null);
  }

  Future<void> test_prepare_sdkClass() async {
    const content = '''
    final a = new [[Ob^ject]]();
    ''';

    await initialize();
    await openFile(mainFileUri, withoutMarkers(content));

    final request = makeRequest(
      Method.textDocument_prepareRename,
      TextDocumentPositionParams(
        textDocument: TextDocumentIdentifier(uri: mainFileUri.toString()),
        position: positionFromMarker(content),
      ),
    );
    final response = await channel.sendRequestToServer(request);

    expect(response.id, equals(request.id));
    expect(response.result, isNull);
    expect(response.error, isNotNull);
    expect(response.error!.code, ServerErrorCodes.RenameNotValid);
    expect(response.error!.message, contains('is defined in the SDK'));
  }

  Future<void> test_prepare_variable() async {
    const content = '''
    main() {
      var variable = 0;
      print([[vari^able]]);
    }
    ''';

    return _test_prepare(content, 'variable');
  }

  Future<void> test_rename_class() {
    const content = '''
    class MyClass {}
    final a = new [[My^Class]]();
    ''';
    const expectedContent = '''
    class MyNewClass {}
    final a = new MyNewClass();
    ''';
    return _test_rename_withDocumentChanges(
        content, 'MyNewClass', expectedContent);
  }

  Future<void> test_rename_class_doesNotRenameFileIfDisabled() async {
    const content = '''
    class Main {}
    final a = new [[Ma^in]]();
    ''';
    const expectedContent = '''
    class MyNewMain {}
    final a = new MyNewMain();
    ''';
    final contents = await _test_rename_withDocumentChanges(
        content, 'MyNewMain', expectedContent);
    // Ensure the only file is still called main.dart.
    expect(contents.keys.single, equals(mainFilePath));
  }

  Future<void> test_rename_class_doesRenameFileAfterPrompt() async {
    const content = '''
    class Main {}
    final a = new [[Ma^in]]();
    ''';
    const expectedContent = '''
    class MyNewMain {}
    final a = new MyNewMain();
    ''';
    final newMainFilePath = join(projectFolderPath, 'lib', 'my_new_main.dart');

    /// Helper that performs the rename and tests the results. Passed below to
    /// provideConfig() so we can wrap this with handlers to provide the
    /// required config.
    Future<void> testRename() async {
      final contents = await _test_rename_withDocumentChanges(
        content,
        'MyNewMain',
        expectedContent,
        expectedFilePath: newMainFilePath,
        workspaceCapabilities: withConfigurationSupport(
            withResourceOperationKinds(emptyWorkspaceClientCapabilities,
                [ResourceOperationKind.Rename])),
      );
      // Ensure we now only have the newly-renamed file and not the old one
      // (its contents will have been checked by the function above).
      expect(contents.keys.single, equals(newMainFilePath));
    }

    /// Helper that will respond to the window/showMessageRequest request from
    /// the server when prompted about renaming the file.
    Future<MessageActionItem> promptHandler(
        ShowMessageRequestParams params) async {
      // Ensure the prompt is as expected.
      expect(params.type, equals(MessageType.Info));
      expect(
          params.message, equals("Rename 'main.dart' to 'my_new_main.dart'?"));
      expect(params.actions, hasLength(2));
      expect(params.actions![0],
          equals(MessageActionItem(title: UserPromptActions.yes)));
      expect(params.actions![1],
          equals(MessageActionItem(title: UserPromptActions.no)));

      // Respond to the request with the required action.
      return params.actions!.first;
    }

    // Run the test and provide the config + prompt handling function.
    return handleExpectedRequest(
      Method.window_showMessageRequest,
      ShowMessageRequestParams.fromJson,
      () => provideConfig(
        testRename,
        {'renameFilesWithClasses': 'prompt'},
      ),
      handler: promptHandler,
    );
  }

  Future<void> test_rename_class_doesRenameFileIfAlwaysEnabled() async {
    const content = '''
    class Main {}
    final a = new [[Ma^in]]();
    ''';
    const expectedContent = '''
    class MyNewMain {}
    final a = new MyNewMain();
    ''';
    final newMainFilePath = join(projectFolderPath, 'lib', 'my_new_main.dart');
    await provideConfig(
      () async {
        final contents = await _test_rename_withDocumentChanges(
          content,
          'MyNewMain',
          expectedContent,
          expectedFilePath: newMainFilePath,
          workspaceCapabilities: withConfigurationSupport(
              withResourceOperationKinds(emptyWorkspaceClientCapabilities,
                  [ResourceOperationKind.Rename])),
        );
        // Ensure we now only have the newly-renamed file and not the old one
        // (its contents will have been checked by the function above).
        expect(contents.keys.single, equals(newMainFilePath));
      },
      {'renameFilesWithClasses': 'always'},
    );
  }

  Future<void> test_rename_class_doesRenameFileIfRenamedFromAnother() async {
    const mainContent = '''
    class Main {}
    ''';
    const otherContent = '''
    import 'main.dart';

    final a = Ma^in();
    ''';
    const expectedContent = '''
    class MyNewMain {}
    ''';
    // Since we don't actually perform the file rename (we only include an
    // instruction for the client to do so), the import will not be updated
    // by us. Instead, the client will send the rename event back to the server
    // and it would be handled normally as if the user had done it locally.
    const expectedOtherContent = '''
    import 'main.dart';

    final a = MyNewMain();
    ''';
    final otherFilePath = join(projectFolderPath, 'lib', 'other.dart');
    final newMainFilePath = join(projectFolderPath, 'lib', 'my_new_main.dart');
    newFile2(mainFilePath, withoutMarkers(mainContent));
    await pumpEventQueue(times: 5000);
    await provideConfig(
      () async {
        final contents = await _test_rename_withDocumentChanges(
          otherContent,
          'MyNewMain',
          expectedOtherContent,
          filePath: otherFilePath,
          contents: {
            otherFilePath: otherContent,
            mainFilePath: mainContent,
          },
          workspaceCapabilities: withConfigurationSupport(
              withResourceOperationKinds(emptyWorkspaceClientCapabilities,
                  [ResourceOperationKind.Rename])),
        );
        // Expect that main was renamed to my_new_main and the other file was
        // updated.
        expect(contents.containsKey(mainFilePath), isFalse);
        expect(contents.containsKey(newMainFilePath), isTrue);
        expect(contents.containsKey(otherFilePath), isTrue);
        expect(contents[newMainFilePath], expectedContent);
        expect(contents[otherFilePath], expectedOtherContent);
      },
      {'renameFilesWithClasses': 'always'},
    );
  }

  Future<void> test_rename_classNewKeyword() {
    const content = '''
    class MyClass {}
    final a = n^ew MyClass();
    ''';
    const expectedContent = '''
    class MyNewClass {}
    final a = new MyNewClass();
    ''';
    return _test_rename_withDocumentChanges(
        content, 'MyNewClass', expectedContent);
  }

  Future<void> test_rename_duplicateName_applyAfterDocumentChanges() async {
    // Perform a refactor that results in a prompt to the user, but then modify
    // the document before accepting/rejecting to make the rename invalid.
    const content = '''
    class MyOtherClass {}
    class MyClass {}
    final a = n^ew MyClass();
    ''';
    final result = await _test_rename_prompt(
      content,
      'MyOtherClass',
      expectedMessage:
          'Library already declares class with name \'MyOtherClass\'.',
      action: UserPromptActions.renameAnyway,
      beforeResponding: () => replaceFile(999, mainFileUri, 'Updated content'),
    );
    expect(result.result, isNull);
    expect(result.error, isNotNull);
    expect(result.error, isResponseError(ErrorCodes.ContentModified));
  }

  Future<void> test_rename_duplicateName_applyAnyway() async {
    const content = '''
    class MyOtherClass {}
    class MyClass {}
    final a = n^ew MyClass();
    ''';
    const expectedContent = '''
    class MyOtherClass {}
    class MyOtherClass {}
    final a = new MyOtherClass();
    ''';
    final response = await _test_rename_prompt(
      content,
      'MyOtherClass',
      expectedMessage:
          'Library already declares class with name \'MyOtherClass\'.',
      action: UserPromptActions.renameAnyway,
    );

    final error = response.error;
    if (error != null) {
      throw error;
    }

    final result =
        WorkspaceEdit.fromJson(response.result as Map<String, Object?>);

    // Ensure applying the changes will give us the expected content.
    final contents = {
      mainFilePath: withoutMarkers(content),
    };
    applyDocumentChanges(
      contents,
      result.documentChanges!,
    );
    expect(contents[mainFilePath], equals(expectedContent));
  }

  Future<void> test_rename_duplicateName_reject() async {
    const content = '''
    class MyOtherClass {}
    class MyClass {}
    final a = n^ew MyClass();
    ''';
    final response = await _test_rename_prompt(
      content,
      'MyOtherClass',
      expectedMessage:
          'Library already declares class with name \'MyOtherClass\'.',
      action: UserPromptActions.cancel,
    );
    // Expect a successful empty response if cancelled.
    expect(response.error, isNull);
    expect(
      WorkspaceEdit.fromJson(response.result as Map<String, Object?>),
      equals(emptyWorkspaceEdit),
    );
  }

  Future<void> test_rename_importPrefix() {
    const content = '''
    import 'dart:async' as myPr^efix;
    ''';
    const expectedContent = '''
    import 'dart:async' as myNewPrefix;
    ''';
    return _test_rename_withDocumentChanges(
        content, 'myNewPrefix', expectedContent);
  }

  Future<void> test_rename_importWithoutPrefix() {
    const content = '''
    imp^ort 'dart:async';
    ''';
    const expectedContent = '''
    import 'dart:async' as myAddedPrefix;
    ''';
    return _test_rename_withDocumentChanges(
        content, 'myAddedPrefix', expectedContent);
  }

  Future<void> test_rename_importWithPrefix() {
    const content = '''
    imp^ort 'dart:async' as myPrefix;
    ''';
    const expectedContent = '''
    import 'dart:async' as myNewPrefix;
    ''';
    return _test_rename_withDocumentChanges(
        content, 'myNewPrefix', expectedContent);
  }

  Future<void> test_rename_invalidRenameLocation() {
    const content = '''
    main() {
      // comm^ent
    }
    ''';
    return _test_rename_withDocumentChanges(content, 'MyNewClass', null);
  }

  Future<void> test_rename_multipleFiles() async {
    final referencedFilePath =
        join(projectFolderPath, 'lib', 'referenced.dart');
    final referencedFileUri = Uri.file(referencedFilePath);
    const mainContent = '''
    import 'referenced.dart';
    final a = new My^Class();
    ''';
    const referencedContent = '''
    class MyClass {}
    ''';
    const expectedMainContent = '''
    import 'referenced.dart';
    final a = new MyNewClass();
    ''';
    const expectedReferencedContent = '''
    class MyNewClass {}
    ''';
    const mainVersion = 111;
    const referencedVersion = 222;

    await initialize(
      workspaceCapabilities:
          withDocumentChangesSupport(emptyWorkspaceClientCapabilities),
    );
    await openFile(mainFileUri, withoutMarkers(mainContent),
        version: mainVersion);
    await openFile(referencedFileUri, withoutMarkers(referencedContent),
        version: referencedVersion);

    final result = (await rename(
      mainFileUri,
      mainVersion,
      positionFromMarker(mainContent),
      'MyNewClass',
    ))!;

    // Ensure applying the changes will give us the expected content.
    final contents = {
      mainFilePath: withoutMarkers(mainContent),
      referencedFilePath: withoutMarkers(referencedContent),
    };
    final documentVersions = {
      mainFilePath: mainVersion,
      referencedFilePath: referencedVersion,
    };
    applyDocumentChanges(
      contents,
      result.documentChanges!,
      expectedVersions: documentVersions,
    );
    expect(contents[mainFilePath], equals(expectedMainContent));
    expect(contents[referencedFilePath], equals(expectedReferencedContent));
  }

  Future<void> test_rename_nonClass_doesNotRenameFile() async {
    const content = '''
    final Ma^in = 'test';
    ''';
    const expectedContent = '''
    final MyNewMain = 'test';
    ''';
    await provideConfig(
      () async {
        final contents = await _test_rename_withDocumentChanges(
          content,
          'MyNewMain',
          expectedContent,
          workspaceCapabilities: withConfigurationSupport(
              withResourceOperationKinds(emptyWorkspaceClientCapabilities,
                  [ResourceOperationKind.Rename])),
        );
        // Ensure the only file is still called main.dart.
        expect(contents.keys.single, equals(mainFilePath));
      },
      {'renameFilesWithClasses': 'always'},
    );
  }

  Future<void> test_rename_rejectedForBadName() async {
    const content = '''
    class MyClass {}
    final a = n^ew MyClass();
    ''';
    final error = await _test_rename_failure(content, 'not a valid class name');
    expect(error.code, equals(ServerErrorCodes.RenameNotValid));
    expect(error.message, contains('name must not contain'));
  }

  Future<void> test_rename_rejectedForSameName() async {
    const content = '''
    class My^Class {}
    ''';
    final error = await _test_rename_failure(content, 'MyClass');
    expect(error.code, equals(ServerErrorCodes.RenameNotValid));
    expect(error.message,
        contains('new name must be different than the current name'));
  }

  Future<void> test_rename_rejectedForStaleDocument() async {
    const content = '''
    class MyClass {}
    final a = n^ew MyClass();
    ''';
    final error =
        await _test_rename_failure(content, 'MyNewClass', openFileVersion: 111);
    expect(error.code, equals(ErrorCodes.ContentModified));
    expect(error.message, contains('Document was modified'));
  }

  Future<void> test_rename_rejectionsDoNotCrashServer() async {
    // Checks that a rename failure does not stop the server from responding
    // as was previously the case in https://github.com/dart-lang/sdk/issues/42573
    // because the error code was duplicated/reused for ClientServerInconsistentState.
    const content = '''
    /// Test Class
    class My^Class {}
    ''';
    final error = await _test_rename_failure(content, 'MyClass');
    expect(error.code, isNotNull);

    // Send any other request to ensure the server is still responsive.
    final hover = await getHover(mainFileUri, positionFromMarker(content));
    expect(hover?.contents, isNotNull);
  }

  Future<void> test_rename_sdkClass() async {
    const content = '''
    final a = new [[Ob^ject]]();
    ''';

    newFile2(mainFilePath, withoutMarkers(content));
    await initialize();

    final request = makeRequest(
      Method.textDocument_rename,
      RenameParams(
        newName: 'Object2',
        textDocument: TextDocumentIdentifier(uri: mainFileUri.toString()),
        position: positionFromMarker(content),
      ),
    );
    final response = await channel.sendRequestToServer(request);

    expect(response.id, equals(request.id));
    expect(response.result, isNull);
    expect(response.error, isNotNull);
    expect(response.error!.code, ServerErrorCodes.RenameNotValid);
    expect(response.error!.message, contains('is defined in the SDK'));
  }

  Future<void> test_rename_usingLegacyChangeInterface() async {
    // This test initializes without support for DocumentChanges (versioning)
    // whereas the other tests all use DocumentChanges support (preferred).
    const content = '''
    class MyClass {}
    final a = new My^Class();
    ''';
    const expectedContent = '''
    class MyNewClass {}
    final a = new MyNewClass();
    ''';

    await initialize();
    await openFile(mainFileUri, withoutMarkers(content), version: 222);

    final result = (await rename(
      mainFileUri,
      222,
      positionFromMarker(content),
      'MyNewClass',
    ))!;

    // Ensure applying the changes will give us the expected content.
    final contents = {
      mainFilePath: withoutMarkers(content),
    };
    applyChanges(contents, result.changes!);
    expect(contents[mainFilePath], equals(expectedContent));
  }

  Future<void> test_rename_variable() {
    const content = '''
    main() {
      var variable = 0;
      print([[vari^able]]);
    }
    ''';
    const expectedContent = '''
    main() {
      var foo = 0;
      print(foo);
    }
    ''';
    return _test_rename_withDocumentChanges(content, 'foo', expectedContent);
  }

  Future<void> test_rename_withoutVersionedIdentifier() {
    // Without sending a document version, the rename should still work because
    // the server should use the version it had at the start of the rename
    // operation.
    const content = '''
    class MyClass {}
    final a = new [[My^Class]]();
    ''';
    const expectedContent = '''
    class MyNewClass {}
    final a = new MyNewClass();
    ''';
    return _test_rename_withDocumentChanges(
        content, 'MyNewClass', expectedContent,
        sendRenameVersion: false);
  }

  Future<void> _test_prepare(
      String content, String? expectedPlaceholder) async {
    await initialize();
    await openFile(mainFileUri, withoutMarkers(content));

    final result =
        await prepareRename(mainFileUri, positionFromMarker(content));

    if (expectedPlaceholder == null) {
      expect(result, isNull);
    } else {
      expect(result!.range, equals(rangeFromMarkers(content)));
      expect(result.placeholder, equals(expectedPlaceholder));
    }
  }

  Future<ResponseError> _test_rename_failure(
    String content,
    String newName, {
    int openFileVersion = 222,
    int renameRequestFileVersion = 222,
  }) async {
    await initialize(
      workspaceCapabilities:
          withDocumentChangesSupport(emptyWorkspaceClientCapabilities),
    );
    await openFile(mainFileUri, withoutMarkers(content),
        version: openFileVersion);

    final result = await renameRaw(
      mainFileUri,
      renameRequestFileVersion,
      positionFromMarker(content),
      newName,
    );

    expect(result.result, isNull);
    expect(result.error, isNotNull);
    return result.error!;
  }

  /// Tests a rename that is expected to cause an error, which will trigger
  /// a ShowMessageRequest from the server to the client to allow the refactor
  /// to be continued or rejected.
  Future<ResponseMessage> _test_rename_prompt(
    String content,
    String newName, {
    required String expectedMessage,
    Future<void> Function()? beforeResponding,
    required String action,
    int openFileVersion = 222,
    int renameRequestFileVersion = 222,
  }) async {
    await initialize(
      workspaceCapabilities:
          withDocumentChangesSupport(emptyWorkspaceClientCapabilities),
    );
    await openFile(mainFileUri, withoutMarkers(content),
        version: openFileVersion);

    // Expect the server to call us back with a ShowMessageRequest prompt about
    // the errors for us to accept/reject.
    return handleExpectedRequest(
      Method.window_showMessageRequest,
      ShowMessageRequestParams.fromJson,
      () => renameRaw(
        mainFileUri,
        renameRequestFileVersion,
        positionFromMarker(content),
        newName,
      ),
      handler: (ShowMessageRequestParams params) async {
        // Ensure the warning prompt is as expected.
        expect(params.type, equals(MessageType.Warning));
        expect(params.message, equals(expectedMessage));
        expect(params.actions, hasLength(2));
        expect(params.actions![0],
            equals(MessageActionItem(title: UserPromptActions.renameAnyway)));
        expect(params.actions![1],
            equals(MessageActionItem(title: UserPromptActions.cancel)));

        // Allow the test to run some code before we send the response.
        await beforeResponding?.call();

        // Respond to the request with the required action.
        return MessageActionItem(title: action);
      },
    );
  }

  Future<Map<String, String>> _test_rename_withDocumentChanges(
    String content,
    String newName,
    String? expectedContent, {
    String? filePath,
    String? expectedFilePath,
    bool sendRenameVersion = true,
    ClientCapabilitiesWorkspace? workspaceCapabilities,
    Map<String, String>? contents,
  }) async {
    contents ??= {};
    filePath ??= mainFilePath;
    expectedFilePath ??= filePath;
    final fileUri = Uri.file(filePath);

    // The specific number doesn't matter here, it's just a placeholder to confirm
    // the values match.
    final documentVersion = 222;
    contents[filePath] = withoutMarkers(content);
    final documentVersions = {
      filePath: documentVersion,
    };

    final initialAnalysis = waitForAnalysisComplete();
    await initialize(
      workspaceCapabilities: withDocumentChangesSupport(
          workspaceCapabilities ?? emptyWorkspaceClientCapabilities),
    );
    await openFile(fileUri, withoutMarkers(content), version: documentVersion);
    await initialAnalysis;

    final result = await rename(
      fileUri,
      sendRenameVersion ? documentVersion : null,
      positionFromMarker(content),
      newName,
    );

    if (expectedContent == null) {
      expect(result, isNull);
    } else {
      // Ensure applying the changes will give us the expected content.
      applyDocumentChanges(
        contents,
        result!.documentChanges!,
        expectedVersions: documentVersions,
      );
      expect(contents[expectedFilePath], equals(expectedContent));
    }

    return contents;
  }
}
