// Copyright (c) 2014, 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_constants.dart';
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:test/test.dart';

import 'analysis_server_base.dart';
import 'constants.dart';

class AbstractCompletionDomainTest extends PubPackageAnalysisServerTest {
  late String completionId;
  late int completionOffset; // TODO(scheglov) remove it
  int? replacementOffset;
  late int replacementLength;
  Map<String, Completer<void>> receivedSuggestionsCompleters = {};
  List<CompletionSuggestion> suggestions = [];
  bool suggestionsDone = false;
  Map<String, List<CompletionSuggestion>> allSuggestions = {};

  void assertHasResult(CompletionSuggestionKind kind, String completion,
      {bool isDeprecated = false,
      bool isPotential = false,
      int? selectionOffset,
      int? replacementOffset,
      int? replacementLength,
      ElementKind? elementKind}) {
    CompletionSuggestion? cs;
    for (var s in suggestions) {
      if (elementKind != null && s.element?.kind != elementKind) {
        return;
      }
      if (s.completion == completion) {
        if (cs == null) {
          cs = s;
        } else {
          fail('expected exactly one $completion but found > 1');
        }
      }
    }
    if (cs == null) {
      var completions = suggestions.map((s) => s.completion).toList();

      var expectationText = '"$completion"';
      if (elementKind != null) {
        expectationText += ' ($elementKind)';
      }

      fail('expected $expectationText, but found\n $completions');
    }
    var suggestion = cs;
    expect(suggestion.kind, equals(kind));
    expect(suggestion.selectionOffset, selectionOffset ?? completion.length);
    expect(suggestion.selectionLength, equals(0));
    expect(suggestion.replacementOffset, equals(replacementOffset));
    expect(suggestion.replacementLength, equals(replacementLength));
    expect(suggestion.isDeprecated, equals(isDeprecated));
    expect(suggestion.isPotential, equals(isPotential));
  }

  void assertNoResult(String completion, {ElementKind? elementKind}) {
    if (suggestions.any((cs) =>
        cs.completion == completion &&
        (elementKind == null || cs.element?.kind == elementKind))) {
      fail('did not expect completion: $completion');
    }
  }

  void assertValidId(String id) {
    expect(id, isNotNull);
    expect(id.isNotEmpty, isTrue);
  }

  Future<void> getCodeSuggestions({
    required String path,
    required String content,
  }) async {
    completionOffset = content.indexOf('^');
    expect(completionOffset, isNot(equals(-1)), reason: 'missing ^');

    var nextOffset = content.indexOf('^', completionOffset + 1);
    expect(nextOffset, equals(-1), reason: 'too many ^');

    newFile(
      path,
      content.substring(0, completionOffset) +
          content.substring(completionOffset + 1),
    );

    return await getSuggestions(
      path: path,
      completionOffset: completionOffset,
    );
  }

  Future<void> getSuggestions({
    required String path,
    required int completionOffset,
  }) async {
    var request =
        CompletionGetSuggestionsParams(path, completionOffset).toRequest('0');
    var response = await handleSuccessfulRequest(request);
    var result = CompletionGetSuggestionsResult.fromResponse(response);
    completionId = result.id;
    assertValidId(completionId);
    await _getResultsCompleter(completionId).future;
    expect(suggestionsDone, isTrue);
  }

  Future<void> getTestCodeSuggestions(String content) {
    return getCodeSuggestions(
      path: testFile.path,
      content: content,
    );
  }

  @override
  Future<void> processNotification(Notification notification) async {
    if (notification.event == COMPLETION_RESULTS) {
      var params = CompletionResultsParams.fromNotification(notification);
      var id = params.id;
      assertValidId(id);
      replacementOffset = params.replacementOffset;
      replacementLength = params.replacementLength;
      suggestionsDone = params.isLast;
      expect(suggestionsDone, isNotNull);
      suggestions = params.results;
      expect(allSuggestions.containsKey(id), isFalse);
      allSuggestions[id] = params.results;
      _getResultsCompleter(id).complete(null);
    } else if (notification.event == SERVER_NOTIFICATION_ERROR) {
      fail('server error: ${notification.toJson()}');
    }
  }

  @override
  Future<void> setUp() async {
    super.setUp();
    await setRoots(included: [workspaceRootPath], excluded: []);
  }

  Completer<void> _getResultsCompleter(String id) {
    return receivedSuggestionsCompleters.putIfAbsent(
        id, () => Completer<void>());
  }
}
