// 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/dart/analysis/results.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer_plugin/protocol/protocol.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/generator.dart';

/// An exception that is thrown when the current completion request should be
/// aborted because either the source changed since the request was made, or
/// a new completion request was received. See [CompletionRequest.checkAborted].
class AbortCompletion {}

/// An object that [CompletionContributor]s use to record completion
/// suggestions.
///
/// Clients may not extend, implement or mix-in this class.
abstract class CompletionCollector {
  /// Set the length of the region of text that should be replaced by the
  /// selected completion suggestion.
  ///
  /// The length can only be set once and applies to all of the suggestions.
  /// Hence, this setter throws a [StateError] if the length has already been
  /// set.
  set length(int length);

  /// Set the offset of the region of text that should be replaced by the
  /// selected completion suggestion.
  ///
  /// The offset can only be set once and applies to all of the suggestions.
  /// Hence, this setter throws a [StateError] if the offset has already been
  /// set.
  set offset(int offset);

  /// Indicates if the collector's offset has been set (and ultimately the
  /// length too).
  bool get offsetIsSet;

  /// Returns length of suggestions currently held.
  int get suggestionsLength;

  /// Record the given completion [suggestion].
  void addSuggestion(CompletionSuggestion suggestion);
}

/// An object used to produce completion suggestions.
///
/// Clients may implement this class when implementing plugins.
abstract class CompletionContributor {
  /// Contribute completion suggestions for the completion location specified by
  /// the given [request] into the given [collector].
  Future<void> computeSuggestions(
      covariant CompletionRequest request, CompletionCollector collector);
}

/// A generator that will generate a 'completion.getSuggestions' response.
///
/// Clients may not extend, implement or mix-in this class.
class CompletionGenerator {
  /// The contributors to be used to generate the completion suggestions.
  final List<CompletionContributor> contributors;

  /// Initialize a newly created completion generator.
  CompletionGenerator(this.contributors);

  /// Create a 'completion.getSuggestions' response for the file with the given
  /// [path]. If any of the contributors throws an exception, also create a
  /// non-fatal 'plugin.error' notification.
  Future<GeneratorResult<CompletionGetSuggestionsResult?>>
      generateCompletionResponse(CompletionRequest request) async {
    var notifications = <Notification>[];
    var collector = CompletionCollectorImpl();
    try {
      for (var contributor in contributors) {
        request.checkAborted();
        try {
          await contributor.computeSuggestions(request, collector);
        } catch (exception, stackTrace) {
          notifications.add(PluginErrorParams(
                  false, exception.toString(), stackTrace.toString())
              .toNotification());
        }
      }
    } on AbortCompletion {
      return GeneratorResult(null, notifications);
    }
    collector.offset ??= request.offset;
    collector.length ??= 0;

    var result = CompletionGetSuggestionsResult(
        collector.offset!, collector.length!, collector.suggestions);
    return GeneratorResult(result, notifications);
  }
}

/// The information about a requested list of completions.
///
/// Clients may not extend, implement or mix-in this class.
abstract class CompletionRequest {
  /// Return the offset within the source at which the completion is being
  /// requested.
  int get offset;

  /// Return the resource provider associated with this request.
  ResourceProvider get resourceProvider;

  /// Throw an [AbortCompletion] if the completion request has been aborted.
  void checkAborted();
}

/// The information about a requested list of completions when completing in a
/// `.dart` file.
///
/// Clients may not extend, implement or mix-in this class.
abstract class DartCompletionRequest implements CompletionRequest {
  /// The analysis result for the file in which the completion is being
  /// requested.
  ResolvedUnitResult get result;
}
