// 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 'dart:async';

import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
import 'package:analysis_server/src/lsp/constants.dart';
import 'package:analysis_server/src/lsp/json_parsing.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

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

void main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(ExtractMethodRefactorCodeActionsTest);
    defineReflectiveTests(ExtractWidgetRefactorCodeActionsTest);
    defineReflectiveTests(ExtractVariableRefactorCodeActionsTest);
    defineReflectiveTests(InlineLocalVariableRefactorCodeActionsTest);
    defineReflectiveTests(InlineMethodRefactorCodeActionsTest);
  });
}

@reflectiveTest
class ExtractMethodRefactorCodeActionsTest extends AbstractCodeActionsTest {
  final extractMethodTitle = 'Extract Method';

  /// A stream of strings (CREATE, BEGIN, END) corresponding to progress
  /// requests and notifications for convenience in testing.
  ///
  /// Analyzing statuses are not included.
  Stream<String> get progressUpdates {
    final controller = StreamController<String>();

    requestsFromServer
        .where((r) => r.method == Method.window_workDoneProgress_create)
        .listen((request) async {
      final params = WorkDoneProgressCreateParams.fromJson(
          request.params as Map<String, Object?>);
      if (params.token != analyzingProgressToken) {
        controller.add('CREATE');
      }
    }, onDone: controller.close);
    notificationsFromServer
        .where((n) => n.method == Method.progress)
        .listen((notification) {
      final params =
          ProgressParams.fromJson(notification.params as Map<String, Object?>);
      if (params.token != analyzingProgressToken) {
        if (WorkDoneProgressBegin.canParse(params.value, nullLspJsonReporter)) {
          controller.add('BEGIN');
        } else if (WorkDoneProgressEnd.canParse(
            params.value, nullLspJsonReporter)) {
          controller.add('END');
        }
      }
    });

    return controller.stream;
  }

  Future<void> test_appliesCorrectEdits() async {
    const content = '''
main() {
  print('Test!');
  [[print('Test!');]]
}
    ''';
    const expectedContent = '''
main() {
  print('Test!');
  newMethod();
}

void newMethod() {
  print('Test!');
}
    ''';
    newFile(mainFilePath, content: withoutMarkers(content));
    await initialize();

    final codeActions = await getCodeActions(mainFileUri.toString(),
        range: rangeFromMarkers(content));
    final codeAction =
        findCommand(codeActions, Commands.performRefactor, extractMethodTitle)!;

    await verifyCodeActionEdits(
        codeAction, withoutMarkers(content), expectedContent);
  }

  Future<void> test_cancelsInProgress() async {
    const content = '''
main() {
  print('Test!');
  [[print('Test!');]]
}
    ''';
    const expectedContent = '''
main() {
  print('Test!');
  newMethod();
}

void newMethod() {
  print('Test!');
}
    ''';
    newFile(mainFilePath, content: withoutMarkers(content));
    await initialize();

    final codeActions = await getCodeActions(mainFileUri.toString(),
        range: rangeFromMarkers(content));
    final codeAction =
        findCommand(codeActions, Commands.performRefactor, extractMethodTitle)!;

    // Respond to any applyEdit requests from the server with successful responses
    // and capturing the last edit.
    late WorkspaceEdit edit;
    requestsFromServer.listen((request) async {
      if (request.method == Method.workspace_applyEdit) {
        final params = ApplyWorkspaceEditParams.fromJson(
            request.params as Map<String, Object?>);
        edit = params.edit;
        respondTo(request, ApplyWorkspaceEditResponse(applied: true));
      }
    });

    // Send two requests together.
    final req1 = executeCodeAction(codeAction);
    final req2 = executeCodeAction(codeAction);

    // Expect the first will have cancelled the second.
    await expectLater(
        req1, throwsA(isResponseError(ErrorCodes.RequestCancelled)));
    await req2;

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

  Future<void> test_contentModified() async {
    const content = '''
main() {
  print('Test!');
  [[print('Test!');]]
}
    ''';
    await initialize();
    await openFile(mainFileUri, withoutMarkers(content));

    final codeActions = await getCodeActions(mainFileUri.toString(),
        range: rangeFromMarkers(content));
    final codeAction =
        findCommand(codeActions, Commands.performRefactor, extractMethodTitle)!;

    // Send an edit request immediately after the refactor request.
    final req1 = executeCodeAction(codeAction);
    await replaceFile(100, mainFileUri, 'new test content');

    // Expect the first to fail because of the modified content.
    await expectLater(
        req1, throwsA(isResponseError(ErrorCodes.ContentModified)));
  }

  Future<void> test_filtersCorrectly() async {
    const content = '''
main() {
  print('Test!');
  [[print('Test!');]]
}
    ''';
    newFile(mainFilePath, content: withoutMarkers(content));
    await initialize();

    final ofKind = (CodeActionKind kind) => getCodeActions(
          mainFileUri.toString(),
          range: rangeFromMarkers(content),
          kinds: [kind],
        );

    // The code above will return a RefactorExtract that should be included
    // by both Refactor and RefactorExtract, but not RefactorExtractFoo or
    // RefactorRewrite
    expect(await ofKind(CodeActionKind.Refactor), isNotEmpty);
    expect(await ofKind(CodeActionKind.RefactorExtract), isNotEmpty);
    expect(await ofKind(CodeActionKind('refactor.extract.foo')), isEmpty);
    expect(await ofKind(CodeActionKind.RefactorRewrite), isEmpty);
  }

  Future<void> test_generatesNames() async {
    const content = '''
Object main() {
  return Container([[Text('Test!')]]);
}

Object Container(Object text) => null;
Object Text(Object text) => null;
    ''';
    const expectedContent = '''
Object main() {
  return Container(text());
}

Object text() => Text('Test!');

Object Container(Object text) => null;
Object Text(Object text) => null;
    ''';
    newFile(mainFilePath, content: withoutMarkers(content));
    await initialize();

    final codeActions = await getCodeActions(mainFileUri.toString(),
        range: rangeFromMarkers(content));
    final codeAction =
        findCommand(codeActions, Commands.performRefactor, extractMethodTitle)!;

    await verifyCodeActionEdits(
        codeAction, withoutMarkers(content), expectedContent);
  }

  Future<void> test_invalidLocation() async {
    const content = '''
import 'dart:convert';
^
main() {}
    ''';
    newFile(mainFilePath, content: content);
    await initialize();

    final codeActions = await getCodeActions(mainFileUri.toString());
    final codeAction =
        findCommand(codeActions, Commands.performRefactor, extractMethodTitle);
    expect(codeAction, isNull);
  }

  Future<void> test_progress_clientProvided() async {
    const content = '''
main() {
  print('Test!');
  [[print('Test!');]]
}
    ''';
    const expectedContent = '''
main() {
  print('Test!');
  newMethod();
}

void newMethod() {
  print('Test!');
}
    ''';
    newFile(mainFilePath, content: withoutMarkers(content));
    await initialize(
        windowCapabilities:
            withWorkDoneProgressSupport(emptyWindowClientCapabilities));

    // Expect begin/end progress updates without a create, since the
    // token was supplied by us (the client).
    expect(progressUpdates, emitsInOrder(['BEGIN', 'END']));

    final codeActions = await getCodeActions(mainFileUri.toString(),
        range: rangeFromMarkers(content));
    final codeAction =
        findCommand(codeActions, Commands.performRefactor, extractMethodTitle)!;

    await verifyCodeActionEdits(
        codeAction, withoutMarkers(content), expectedContent,
        workDoneToken: clientProvidedTestWorkDoneToken);
  }

  Future<void> test_progress_notSupported() async {
    const content = '''
main() {
  print('Test!');
  [[print('Test!');]]
}
    ''';
    const expectedContent = '''
main() {
  print('Test!');
  newMethod();
}

void newMethod() {
  print('Test!');
}
    ''';
    newFile(mainFilePath, content: withoutMarkers(content));
    await initialize();

    var didGetProgressNotifications = false;
    notificationsFromServer
        .where((n) => n.method == Method.progress)
        .listen((_) => didGetProgressNotifications = true);

    final codeActions = await getCodeActions(mainFileUri.toString(),
        range: rangeFromMarkers(content));
    final codeAction =
        findCommand(codeActions, Commands.performRefactor, extractMethodTitle)!;

    await verifyCodeActionEdits(
        codeAction, withoutMarkers(content), expectedContent);

    expect(didGetProgressNotifications, isFalse);
  }

  Future<void> test_progress_serverGenerated() async {
    const content = '''
main() {
  print('Test!');
  [[print('Test!');]]
}
    ''';
    const expectedContent = '''
main() {
  print('Test!');
  newMethod();
}

void newMethod() {
  print('Test!');
}
    ''';
    newFile(mainFilePath, content: withoutMarkers(content));
    await initialize(
        windowCapabilities:
            withWorkDoneProgressSupport(emptyWindowClientCapabilities));

    final codeActions = await getCodeActions(mainFileUri.toString(),
        range: rangeFromMarkers(content));
    final codeAction =
        findCommand(codeActions, Commands.performRefactor, extractMethodTitle)!;

    // Ensure the progress messages come through and in the correct order.
    expect(progressUpdates, emitsInOrder(['CREATE', 'BEGIN', 'END']));

    await verifyCodeActionEdits(
        codeAction, withoutMarkers(content), expectedContent);
  }
}

@reflectiveTest
class ExtractVariableRefactorCodeActionsTest extends AbstractCodeActionsTest {
  final extractVariableTitle = 'Extract Local Variable';

  Future<void> test_appliesCorrectEdits() async {
    const content = '''
main() {
  foo([[1 + 2]]);
}

void foo(int arg) {}
    ''';
    const expectedContent = '''
main() {
  var arg = 1 + 2;
  foo(arg);
}

void foo(int arg) {}
    ''';
    newFile(mainFilePath, content: withoutMarkers(content));
    await initialize();

    final codeActions = await getCodeActions(mainFileUri.toString(),
        range: rangeFromMarkers(content));
    final codeAction = findCommand(
        codeActions, Commands.performRefactor, extractVariableTitle)!;

    await verifyCodeActionEdits(
        codeAction, withoutMarkers(content), expectedContent);
  }

  Future<void> test_doesNotCreateNameConflicts() async {
    const content = '''
main() {
  var arg = "test";
  foo([[1 + 2]]);
}

void foo(int arg) {}
    ''';
    const expectedContent = '''
main() {
  var arg = "test";
  var arg2 = 1 + 2;
  foo(arg2);
}

void foo(int arg) {}
    ''';
    newFile(mainFilePath, content: withoutMarkers(content));
    await initialize();

    final codeActions = await getCodeActions(mainFileUri.toString(),
        range: rangeFromMarkers(content));
    final codeAction = findCommand(
        codeActions, Commands.performRefactor, extractVariableTitle)!;

    await verifyCodeActionEdits(
        codeAction, withoutMarkers(content), expectedContent);
  }
}

@reflectiveTest
class ExtractWidgetRefactorCodeActionsTest extends AbstractCodeActionsTest {
  final extractWidgetTitle = 'Extract Widget';

  @override
  void setUp() {
    super.setUp();
    writePackageConfig(
      projectFolderPath,
      flutter: true,
    );
  }

  Future<void> test_appliesCorrectEdits() async {
    const content = '''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Row(
      children: <Widget>[
        new [[Column]](
          children: <Widget>[
            new Text('AAA'),
            new Text('BBB'),
          ],
        ),
        new Text('CCC'),
        new Text('DDD'),
      ],
    );
  }
}
    ''';
    const expectedContent = '''
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Row(
      children: <Widget>[
        NewWidget(),
        new Text('CCC'),
        new Text('DDD'),
      ],
    );
  }
}

class NewWidget extends StatelessWidget {
  const NewWidget({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return new Column(
      children: <Widget>[
        new Text('AAA'),
        new Text('BBB'),
      ],
    );
  }
}
    ''';
    newFile(mainFilePath, content: withoutMarkers(content));
    await initialize();

    final codeActions = await getCodeActions(mainFileUri.toString(),
        range: rangeFromMarkers(content));
    final codeAction =
        findCommand(codeActions, Commands.performRefactor, extractWidgetTitle)!;

    await verifyCodeActionEdits(
        codeAction, withoutMarkers(content), expectedContent);
  }

  Future<void> test_invalidLocation() async {
    const content = '''
import 'dart:convert';
^
main() {}
    ''';
    newFile(mainFilePath, content: content);
    await initialize();

    final codeActions = await getCodeActions(mainFileUri.toString());
    final codeAction =
        findCommand(codeActions, Commands.performRefactor, extractWidgetTitle);
    expect(codeAction, isNull);
  }
}

@reflectiveTest
class InlineLocalVariableRefactorCodeActionsTest
    extends AbstractCodeActionsTest {
  final inlineVariableTitle = 'Inline Local Variable';

  Future<void> test_appliesCorrectEdits() async {
    const content = '''
void main() {
  var a^ = 1;
  print(a);
  print(a);
  print(a);
}
    ''';
    const expectedContent = '''
void main() {
  print(1);
  print(1);
  print(1);
}
    ''';
    newFile(mainFilePath, content: withoutMarkers(content));
    await initialize();

    final codeActions = await getCodeActions(mainFileUri.toString(),
        position: positionFromMarker(content));
    final codeAction = findCommand(
        codeActions, Commands.performRefactor, inlineVariableTitle)!;

    await verifyCodeActionEdits(
        codeAction, withoutMarkers(content), expectedContent);
  }
}

@reflectiveTest
class InlineMethodRefactorCodeActionsTest extends AbstractCodeActionsTest {
  final inlineMethodTitle = 'Inline Method';

  Future<void> test_inlineAtCallSite() async {
    const content = '''
void foo1() {
  ba^r();
}

void foo2() {
  bar();
}

void bar() {
  print('test');
}
    ''';
    const expectedContent = '''
void foo1() {
  print('test');
}

void foo2() {
  bar();
}

void bar() {
  print('test');
}
    ''';
    newFile(mainFilePath, content: withoutMarkers(content));
    await initialize();

    final codeActions = await getCodeActions(mainFileUri.toString(),
        position: positionFromMarker(content));
    final codeAction =
        findCommand(codeActions, Commands.performRefactor, inlineMethodTitle)!;

    await verifyCodeActionEdits(
        codeAction, withoutMarkers(content), expectedContent);
  }

  Future<void> test_inlineAtMethod() async {
    const content = '''
void foo1() {
  bar();
}

void foo2() {
  bar();
}

void ba^r() {
  print('test');
}
    ''';
    const expectedContent = '''
void foo1() {
  print('test');
}

void foo2() {
  print('test');
}
    ''';
    newFile(mainFilePath, content: withoutMarkers(content));
    await initialize();

    final codeActions = await getCodeActions(mainFileUri.toString(),
        position: positionFromMarker(content));
    final codeAction =
        findCommand(codeActions, Commands.performRefactor, inlineMethodTitle)!;

    await verifyCodeActionEdits(
        codeAction, withoutMarkers(content), expectedContent);
  }
}
