// 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/src/protocol_server.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'available_suggestions_base.dart';

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

@reflectiveTest
class GetSuggestionDetailsTest extends AvailableSuggestionsBase {
  Future<void> test_enum() async {
    newFile('/home/test/lib/a.dart', content: r'''
enum MyEnum {
  aaa, bbb
}
''');
    addTestFile(r'''
main() {} // ref
''');

    var set = await waitForSetWithUri('package:test/a.dart');
    var result = await _getSuggestionDetails(
      _buildRequest(
        id: set.id,
        label: 'MyEnum.aaa',
        offset: testCode.indexOf('} // ref'),
      ),
    );

    expect(result.completion, 'MyEnum.aaa');
    _assertTestFileChange(result.change!, r'''
import 'package:test/a.dart';

main() {} // ref
''');
  }

  Future<void> test_existingImport() async {
    addTestFile(r'''
import 'dart:math';

main() {} // ref
''');

    var mathSet = await waitForSetWithUri('dart:math');
    var result = await _getSuggestionDetails(
      _buildRequest(
        id: mathSet.id,
        label: 'sin',
        offset: testCode.indexOf('} // ref'),
      ),
    );

    expect(result.completion, 'sin');
    _assertEmptyChange(result.change!);
  }

  Future<void> test_existingImport_prefixed() async {
    addTestFile(r'''
import 'dart:math' as math;

main() {} // ref
''');

    var mathSet = await waitForSetWithUri('dart:math');
    var result = await _getSuggestionDetails(
      _buildRequest(
        id: mathSet.id,
        label: 'sin',
        offset: testCode.indexOf('} // ref'),
      ),
    );

    expect(result.completion, 'math.sin');
    _assertEmptyChange(result.change!);
  }

  Future<void> test_invalid_library() async {
    addTestFile('');

    var response = await waitResponse(
      _buildRequest(id: -1, label: 'foo', offset: 0),
    );
    expect(response.error!.code, RequestErrorCode.INVALID_PARAMETER);
  }

  Future<void> test_newImport() async {
    addTestFile(r'''
main() {} // ref
''');

    var mathSet = await waitForSetWithUri('dart:math');
    var result = await _getSuggestionDetails(
      _buildRequest(
        id: mathSet.id,
        label: 'sin',
        offset: testCode.indexOf('} // ref'),
      ),
    );

    expect(result.completion, 'sin');
    _assertTestFileChange(result.change!, r'''
import 'dart:math';

main() {} // ref
''');
  }

  Future<void> test_newImport_afterLibraryBeforeFirstImportsAnnotation() async {
    // Annotations are only treated as being for the file if they are on the first
    // directive of the file.
    addTestFile(r'''
library foo;

@myAnnotation
import 'package:zzz';

main() {} // ref
''');

    var mathSet = await waitForSetWithUri('dart:math');
    var result = await _getSuggestionDetails(
      _buildRequest(
        id: mathSet.id,
        label: 'sin',
        offset: testCode.indexOf('} // ref'),
      ),
    );

    expect(result.completion, 'sin');
    _assertTestFileChange(result.change!, r'''
library foo;

import 'dart:math';

@myAnnotation
import 'package:zzz';

main() {} // ref
''');
  }

  Future<void> test_newImport_betweenAnnotationAndFirstImport() async {
    // Annotations attached to the first import in a file are considered
    // to be for the file, so if an import is inserted in the top position, it
    // should go after the annotation.
    addTestFile(r'''
@myAnnotation

import 'package:zzz';

main() {} // ref
''');

    var mathSet = await waitForSetWithUri('dart:math');
    var result = await _getSuggestionDetails(
      _buildRequest(
        id: mathSet.id,
        label: 'sin',
        offset: testCode.indexOf('} // ref'),
      ),
    );

    expect(result.completion, 'sin');
    _assertTestFileChange(result.change!, r'''
@myAnnotation

import 'dart:math';

import 'package:zzz';

main() {} // ref
''');
  }

  Future<void> test_newImport_notBetweenAnnotationAndNonFirstImport() async {
    // Annotations on non-first directives should not be kept above the newly
    // imported imports (opposite of test_newImport_betweenAnnotationAndFirstImport).
    addTestFile(r'''
import 'dart:async';
@myAnnotation
import 'package:zzz';

main() {} // ref
''');

    var mathSet = await waitForSetWithUri('dart:math');
    var result = await _getSuggestionDetails(
      _buildRequest(
        id: mathSet.id,
        label: 'sin',
        offset: testCode.indexOf('} // ref'),
      ),
    );

    expect(result.completion, 'sin');
    _assertTestFileChange(result.change!, r'''
import 'dart:async';
import 'dart:math';
@myAnnotation
import 'package:zzz';

main() {} // ref
''');
  }

  Future<void> test_newImport_part() async {
    var partCode = r'''
part of 'test.dart';

main() {} // ref
''';
    var partPath = newFile('/home/test/lib/a.dart', content: partCode).path;
    addTestFile(r'''
part 'a.dart';
''');

    var mathSet = await waitForSetWithUri('dart:math');
    var result = await _getSuggestionDetails(
      _buildRequest(
        file: partPath,
        id: mathSet.id,
        label: 'sin',
        offset: partCode.indexOf('} // ref'),
      ),
    );

    expect(result.completion, 'sin');
    _assertTestFileChange(result.change!, r'''
import 'dart:math';

part 'a.dart';
''');
  }

  void _assertEmptyChange(SourceChange change) {
    expect(change.edits, isEmpty);
  }

  void _assertTestFileChange(SourceChange change, String expected) {
    var fileEdits = change.edits;
    expect(fileEdits, hasLength(1));

    var fileEdit = fileEdits[0];
    expect(fileEdit.file, testFile);

    var edits = fileEdit.edits;
    expect(SourceEdit.applySequence(testCode, edits), expected);
  }

  Request _buildRequest({
    String? file,
    required int id,
    required String label,
    required int offset,
  }) {
    return CompletionGetSuggestionDetailsParams(
      file ?? testFile,
      id,
      label,
      offset,
    ).toRequest('0');
  }

  Future<CompletionGetSuggestionDetailsResult> _getSuggestionDetails(
      Request request) async {
    var response = await waitResponse(request);
    return CompletionGetSuggestionDetailsResult.fromResponse(response);
  }
}
