// 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 'dart:async';

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.
   */
  void 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.
   */
  void 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 {
    // TODO(brianwilkerson) Determine whether this await is necessary.
    await null;
    List<Notification> notifications = <Notification>[];
    CompletionCollectorImpl collector = new CompletionCollectorImpl();
    try {
      for (CompletionContributor contributor in contributors) {
        request.checkAborted();
        try {
          await contributor.computeSuggestions(request, collector);
        } catch (exception, stackTrace) {
          notifications.add(new PluginErrorParams(
                  false, exception.toString(), stackTrace.toString())
              .toNotification());
        }
      }
    } on AbortCompletion {
      return new GeneratorResult(null, notifications);
    }
    collector.offset ??= request.offset;
    collector.length ??= 0;

    CompletionGetSuggestionsResult result = new CompletionGetSuggestionsResult(
        collector.offset, collector.length, collector.suggestions);
    return new 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;
}
