// Copyright (c) 2017, 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:analyzer_plugin/plugin/completion_mixin.dart';
import 'package:analyzer_plugin/plugin/plugin.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/protocol/protocol_generated.dart';
import 'package:analyzer_plugin/src/utilities/completion/completion_core.dart';
import 'package:analyzer_plugin/utilities/completion/completion_core.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'mocks.dart';
import 'plugin_test.dart';

void main() {
  defineReflectiveTests(CompletionMixinTest);
}

@reflectiveTest
class CompletionMixinTest extends AbstractPluginTest {
  late String packagePath1;
  late String filePath1;
  late ContextRoot contextRoot1;

  @override
  ServerPlugin createPlugin() {
    return _TestServerPlugin(resourceProvider);
  }

  @override
  Future<void> setUp() async {
    await super.setUp();
    packagePath1 = convertPath('/package1');
    filePath1 = join(packagePath1, 'lib', 'test.dart');
    newFile(filePath1, 'int foo = bar;');
    contextRoot1 = ContextRoot(packagePath1, <String>[]);
  }

  Future<void> test_handleCompletionGetSuggestions() async {
    await plugin.handleAnalysisSetContextRoots(
        AnalysisSetContextRootsParams([contextRoot1]));

    var result = await plugin.handleCompletionGetSuggestions(
        CompletionGetSuggestionsParams(filePath1, 13));
    expect(result, isNotNull);
    expect(result.results, hasLength(3));
  }
}

class _TestCompletionContributor implements CompletionContributor {
  List<CompletionSuggestion> suggestions;

  _TestCompletionContributor(this.suggestions);

  @override
  Future<void> computeSuggestions(
      CompletionRequest request, CompletionCollector collector) async {
    if ((collector as CompletionCollectorImpl).offset == null) {
      collector.offset = 1;
      collector.length = 2;
    }
    for (var suggestion in suggestions) {
      collector.addSuggestion(suggestion);
    }
  }
}

class _TestServerPlugin extends MockServerPlugin with CompletionMixin {
  _TestServerPlugin(super.resourceProvider);

  CompletionSuggestion createSuggestion() {
    return CompletionSuggestion(
        CompletionSuggestionKind.IDENTIFIER, 1, '', 0, 0, false, false);
  }

  @override
  List<CompletionContributor> getCompletionContributors(String path) {
    return <CompletionContributor>[
      _TestCompletionContributor(
          <CompletionSuggestion>[createSuggestion(), createSuggestion()]),
      _TestCompletionContributor(<CompletionSuggestion>[createSuggestion()]),
    ];
  }

  @override
  Future<CompletionRequest> getCompletionRequest(
      CompletionGetSuggestionsParams parameters) async {
    var result = MockResolvedUnitResult();
    return DartCompletionRequestImpl(
        resourceProvider, parameters.offset, result);
  }
}
