// Copyright (c) 2022, 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/src/protocol_server.dart';
import 'package:analysis_server/src/services/snippets/dart/switch_statement.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'test_support.dart';

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

@reflectiveTest
class SwitchStatementTest extends DartSnippetProducerTest {
  @override
  final generator = SwitchStatement.new;

  @override
  String get label => SwitchStatement.label;

  @override
  String get prefix => SwitchStatement.prefix;

  Future<void> test_switch() async {
    var code = r'''
void f() {
  sw^
}''';
    final snippet = await expectValidSnippet(code);
    expect(snippet.prefix, prefix);
    expect(snippet.label, label);
    expect(snippet.change.edits, hasLength(1));
    code = withoutMarkers(code);
    for (var edit in snippet.change.edits) {
      code = SourceEdit.applySequence(code, edit.edits);
    }
    expect(code, '''
void f() {
  switch (expression) {
    case value:
      
      break;
    default:
  }
}''');
    expect(snippet.change.selection!.file, testFile);
    expect(snippet.change.selection!.offset, 57);
    expect(snippet.change.linkedEditGroups.map((group) => group.toJson()), [
      // expression
      {
        'positions': [
          {'file': testFile, 'offset': 21},
        ],
        'length': 10,
        'suggestions': []
      },
      // value
      {
        'positions': [
          {'file': testFile, 'offset': 44},
        ],
        'length': 5,
        'suggestions': []
      },
    ]);
  }

  Future<void> test_switch_indentedInsideBlock() async {
    var code = r'''
void f() {
  if (true) {
    sw^
  }
}''';
    final snippet = await expectValidSnippet(code);
    expect(snippet.prefix, prefix);
    expect(snippet.label, label);
    expect(snippet.change.edits, hasLength(1));
    code = withoutMarkers(code);
    for (var edit in snippet.change.edits) {
      code = SourceEdit.applySequence(code, edit.edits);
    }
    expect(code, '''
void f() {
  if (true) {
    switch (expression) {
      case value:
        
        break;
      default:
    }
  }
}''');
    expect(snippet.change.selection!.file, testFile);
    expect(snippet.change.selection!.offset, 77);
    expect(snippet.change.linkedEditGroups.map((group) => group.toJson()), [
      // expression
      {
        'positions': [
          {'file': testFile, 'offset': 37},
        ],
        'length': 10,
        'suggestions': []
      },
      // value
      {
        'positions': [
          {'file': testFile, 'offset': 62},
        ],
        'length': 5,
        'suggestions': []
      },
    ]);
  }
}
