// 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.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 = '''
    void f() {
      // 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 = '''
    void f() {
      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');
    newFile(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 = '''
    void f() {
      // 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]]();
    ''';

    newFile(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 = '''
    void f() {
      var variable = 0;
      print([[vari^able]]);
    }
    ''';
    const expectedContent = '''
    void f() {
      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,
    WorkspaceClientCapabilities? 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;
  }
}
