// Copyright (c) 2021, 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:analyzer/source/line_info.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'server_abstract.dart';

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

/// Additional tests are in
///
/// test/src/computer/selection_range_computer_test.dart
@reflectiveTest
class SelectionRangeTest extends AbstractLspAnalysisServerTest {
  Future<void> test_multiple() async {
    final content = '''
class Foo {
  void a() { /*1*/ }
  void b() { /*2*/ }
}
''';

    await initialize();
    await openFile(mainFileUri, content);
    final lineInfo = LineInfo.fromContent(content);

    // Send a request for two positions.
    final regions = await getSelectionRanges(mainFileUri, [
      positionFromOffset(content.indexOf('/*1*/'), content),
      positionFromOffset(content.indexOf('/*2*/'), content),
    ]);
    expect(regions!.length, equals(2));
    final firstTexts =
        _getSelectionRangeText(lineInfo, content, regions[0]).toList();
    final secondTexts =
        _getSelectionRangeText(lineInfo, content, regions[1]).toList();

    expect(
        firstTexts,
        equals([
          '{ /*1*/ }',
          'void a() { /*1*/ }',
          content.trim(), // Whole content minus the trailing newline
        ]));
    expect(
        secondTexts,
        equals([
          '{ /*2*/ }',
          'void b() { /*2*/ }',
          content.trim(), // Whole content minus the trailing newline
        ]));
  }

  Future<void> test_single() async {
    final content = '''
class Foo<T> {
  void a(String b) {
    print((1 ^+ 2) * 3);
  }
}
''';
    final contentWithoutMarker = withoutMarkers(content);

    await initialize();
    await openFile(mainFileUri, contentWithoutMarker);
    final lineInfo = LineInfo.fromContent(contentWithoutMarker);

    // The returned List corresponds to the input list of positions, and not
    // the set of ranges - each range within that list has a (recusrive) parent
    // to walk up all ranges for that position.
    final regions =
        await getSelectionRanges(mainFileUri, [positionFromMarker(content)]);
    expect(regions!.length, equals(1)); // Only one position was sent.
    final regionTexts =
        _getSelectionRangeText(lineInfo, contentWithoutMarker, regions.first)
            .toList();

    expect(
        regionTexts,
        equals([
          '1 + 2',
          '(1 + 2)',
          '(1 + 2) * 3',
          '((1 + 2) * 3)',
          'print((1 + 2) * 3)',
          'print((1 + 2) * 3);',
          '{\n    print((1 + 2) * 3);\n  }',
          'void a(String b) {\n    print((1 + 2) * 3);\n  }',
          'class Foo<T> {\n  void a(String b) {\n    print((1 + 2) * 3);\n  }\n}',
        ]));
  }

  Iterable<String> _getSelectionRangeText(
      LineInfo lineInfo, String content, SelectionRange range) sync* {
    yield _rangeOfText(lineInfo, content, range.range);
    final parent = range.parent;
    if (parent != null) {
      yield* _getSelectionRangeText(lineInfo, content, parent);
    }
  }

  String _rangeOfText(LineInfo lineInfo, String content, Range range) {
    final startPos = range.start;
    final endPos = range.end;
    final start = lineInfo.getOffsetOfLine(startPos.line) + startPos.character;
    final end = lineInfo.getOffsetOfLine(endPos.line) + endPos.character;
    return content.substring(start, end);
  }
}
