// 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.

library services.completion.computer;

import 'dart:async';

import 'package:analysis_services/completion/completion_suggestion.dart';
import 'package:analysis_services/search/search_engine.dart';
import 'package:analysis_services/src/completion/dart_completion_manager.dart';
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';

/**
 * The base class for computing code completion suggestions.
 */
abstract class CompletionComputer {
  AnalysisContext context;
  Source source;
  int offset;
  SearchEngine searchEngine;

  /**
   * Computes the initial set of [CompletionSuggestion]s based on
   * the compilation [unit], the AST [node] in which the completion occurred,
   * and information already cached in the analysis context.
   * The supplied [unit] and [node] may not be resolved.
   * This method should execute quickly and not block waiting for any analysis.
   * Returns `true` if the computer's work is complete
   * or `false` if [computeFull] should be called to complete the work.
   */
  bool computeFast(CompilationUnit unit, AstNode node,
      List<CompletionSuggestion> suggestions);

  /**
   * Computes the complete set of [CompletionSuggestion]s based on
   * the resolved compilation [unit] and the resolved AST [node] in which the
   * completion occurred.
   * Returns `true` if the receiver modified the list of suggestions.
   */
  Future<bool> computeFull(CompilationUnit unit, AstNode node,
      List<CompletionSuggestion> suggestions);
}

/**
 * Manages `CompletionComputer`s for a given completion request.
 */
abstract class CompletionManager {

  StreamController<CompletionResult> controller;

  /**
   * Compute completion results and append them to the stream.
   * Subclasses should override this method, append at least one result
   * to the [controller], and close the controller stream once complete.
   * Clients should not call this method directly as it is automatically called
   * when a client listens to the stream returned by [results].
   */
  void compute();

  /**
   * Generate a stream of code completion results.
   */
  Stream<CompletionResult> results() {
    controller = new StreamController<CompletionResult>(onListen: () {
      scheduleMicrotask(compute);
    });
    return controller.stream;
  }

  /**
   * Create a manager for the given request.
   */
  static CompletionManager create(AnalysisContext context, Source source,
      int offset, SearchEngine searchEngine) {
    if (context != null) {
      if (AnalysisEngine.isDartFileName(source.shortName)) {
        return new DartCompletionManager(context, source, offset, searchEngine);
      }
    }
    return new NoOpCompletionManager(source, offset);
  }
}

/**
 * Code completion result generated by an [CompletionManager].
 */
class CompletionResult {

  /**
   * The length of the text to be replaced if the remainder of the identifier
   * containing the cursor is to be replaced when the suggestion is applied
   * (that is, the number of characters in the existing identifier).
   */
  final int replacementLength;

  /**
   * The offset of the start of the text to be replaced. This will be different
   * than the offset used to request the completion suggestions if there was a
   * portion of an identifier before the original offset. In particular, the
   * replacementOffset will be the offset of the beginning of said identifier.
   */
  final int replacementOffset;

  /**
   * The suggested completions.
   */
  final List<CompletionSuggestion> suggestions;

  /**
   * `true` if this is that last set of results that will be returned
   * for the indicated completion.
   */
  final bool last;

  CompletionResult(this.replacementOffset, this.replacementLength,
      this.suggestions, this.last);
}


class NoOpCompletionManager extends CompletionManager {
  final Source source;
  final int offset;

  NoOpCompletionManager(this.source, this.offset);

  @override
  void compute() {
    controller.add(new CompletionResult(offset, 0, [], true));
  }
}
