// Copyright (c) 2015, 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/protocol/protocol.dart';
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/edit/edit_domain.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../analysis_abstract.dart';
import '../mocks.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(FormatTest);
  });
}

@reflectiveTest
class FormatTest extends AbstractAnalysisTest {
  @override
  void setUp() {
    super.setUp();
    createProject();
    handler = new EditDomainHandler(server);
  }

  Future test_format_longLine() {
    String content = '''
fun(firstParam, secondParam, thirdParam, fourthParam) {
  if (firstParam.noNull && secondParam.noNull && thirdParam.noNull && fourthParam.noNull) {}
}
''';
    addTestFile(content);
    return waitForTasksFinished().then((_) {
      EditFormatResult formatResult = _formatAt(0, 3, lineLength: 100);

      expect(formatResult.edits, isNotNull);
      expect(formatResult.edits, hasLength(0));

      expect(formatResult.selectionOffset, equals(0));
      expect(formatResult.selectionLength, equals(3));
    });
  }

  Future test_format_noOp() {
    // Already formatted source
    addTestFile('''
main() {
  int x = 3;
}
''');
    return waitForTasksFinished().then((_) {
      EditFormatResult formatResult = _formatAt(0, 3);
      expect(formatResult.edits, isNotNull);
      expect(formatResult.edits, hasLength(0));
    });
  }

  Future test_format_noSelection() async {
    addTestFile('''
main() { int x = 3; }
''');
    await waitForTasksFinished();
    EditFormatResult formatResult = _formatAt(0, 0);

    expect(formatResult.edits, isNotNull);
    expect(formatResult.edits, hasLength(1));

    SourceEdit edit = formatResult.edits[0];
    expect(edit.replacement, equals('''
main() {
  int x = 3;
}
'''));
    expect(formatResult.selectionOffset, equals(0));
    expect(formatResult.selectionLength, equals(0));
  }

  Future test_format_simple() {
    addTestFile('''
main() { int x = 3; }
''');
    return waitForTasksFinished().then((_) {
      EditFormatResult formatResult = _formatAt(0, 3);

      expect(formatResult.edits, isNotNull);
      expect(formatResult.edits, hasLength(1));

      SourceEdit edit = formatResult.edits[0];
      expect(edit.replacement, equals('''
main() {
  int x = 3;
}
'''));
      expect(formatResult.selectionOffset, equals(0));
      expect(formatResult.selectionLength, equals(3));
    });
  }

  Future test_format_withErrors() {
    addTestFile('''
main() { int x =
''');
    return waitForTasksFinished().then((_) {
      Request request = new EditFormatParams(testFile, 0, 3).toRequest('0');
      Response response = handler.handleRequest(request);
      expect(response, isResponseFailure('0'));
    });
  }

  EditFormatResult _formatAt(int selectionOffset, int selectionLength,
      {int lineLength}) {
    Request request = new EditFormatParams(
            testFile, selectionOffset, selectionLength,
            lineLength: lineLength)
        .toRequest('0');
    Response response = handleSuccessfulRequest(request);
    return new EditFormatResult.fromResponse(response);
  }
}
