// 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');
    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 = '''
    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]]();
    ''';

    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 = '''
    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;
  }
}
