// 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 test.services.completion.suggestion;

import 'dart:async';

import 'package:analysis_server/completion/completion_core.dart'
    show CompletionRequest, CompletionResult;
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/protocol.dart';
import 'package:analysis_server/src/services/completion/completion_manager.dart';
import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
import 'package:analysis_server/src/services/index/index.dart';
import 'package:analysis_server/src/services/index/local_memory_index.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analysis_server/src/services/search/search_engine_internal.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unittest/unittest.dart';

import '../../abstract_single_unit.dart';
import '../../operation/operation_queue_test.dart';
import '../../utils.dart';

main() {
  initializeTestEnvironment();
  defineReflectiveTests(DartCompletionManagerTest);
}

/**
 * Returns a [Future] that completes after pumping the event queue [times]
 * times. By default, this should pump the event queue enough times to allow
 * any code to run, as long as it's not waiting on some external event.
 */
Future pumpEventQueue([int times = 20]) {
  if (times == 0) return new Future.value();
  // We use a delayed future to allow microtask events to finish. The
  // Future.value or Future() constructors use scheduleMicrotask themselves and
  // would therefore not wait for microtask callbacks that are scheduled after
  // invoking this method.
  return new Future.delayed(Duration.ZERO, () => pumpEventQueue(times - 1));
}

@reflectiveTest
class DartCompletionManagerTest extends AbstractSingleUnitTest {
  Index index;
  SearchEngineImpl searchEngine;
  Source source;
  DartCompletionManager manager;
  MockCompletionContributor contributor1;
  MockCompletionContributor contributor2;
  CompletionSuggestion suggestion1;
  CompletionSuggestion suggestion2;
  bool _continuePerformingAnalysis = true;

  void resolveLibrary() {
    context.resolveCompilationUnit(
        source, context.computeLibraryElement(source));
  }

  @override
  void setUp() {
    super.setUp();
    index = createLocalMemoryIndex();
    searchEngine = new SearchEngineImpl(index);
    source = addSource('/does/not/exist.dart', '');
    manager = new DartCompletionManager.create(context, searchEngine, source);
    suggestion1 = new CompletionSuggestion(CompletionSuggestionKind.INVOCATION,
        DART_RELEVANCE_DEFAULT, "suggestion1", 1, 1, false, false);
    suggestion2 = new CompletionSuggestion(CompletionSuggestionKind.IDENTIFIER,
        DART_RELEVANCE_DEFAULT, "suggestion2", 2, 2, false, false);
    new Future(_performAnalysis);
  }

  @override
  void tearDown() {
    _continuePerformingAnalysis = false;
  }

  test_compute_fastAndFull() {
    contributor1 = new MockCompletionContributor(suggestion1, null);
    contributor2 = new MockCompletionContributor(null, suggestion2);
    manager.contributors = [contributor1, contributor2];
    int count = 0;
    bool done = false;
    AnalysisServer server = new AnalysisServerMock(searchEngine: searchEngine);
    CompletionRequest completionRequest =
        new CompletionRequestImpl(server, context, source, 0);
    manager.results(completionRequest).listen((CompletionResult r) {
      bool isLast = r is CompletionResultImpl ? r.isLast : true;
      switch (++count) {
        case 1:
          contributor1.assertCalls(context, source, 0, searchEngine);
          contributor2.assertCalls(context, source, 0, searchEngine);
          expect(isLast, isFalse);
          expect(r.suggestions, hasLength(1));
          expect(r.suggestions, contains(suggestion1));
          resolveLibrary();
          break;
        case 2:
          contributor1.assertFull(0);
          contributor2.assertFull(1);
          expect(isLast, isTrue);
          expect(r.suggestions, hasLength(2));
          expect(r.suggestions, contains(suggestion1));
          expect(r.suggestions, contains(suggestion2));
          break;
        default:
          fail('unexpected');
      }
    }, onDone: () {
      done = true;
      expect(count, equals(2));
    });
    return pumpEventQueue().then((_) {
      expect(done, isTrue);
    });
  }

  test_compute_fastOnly() {
    contributor1 = new MockCompletionContributor(suggestion1, null);
    contributor2 = new MockCompletionContributor(suggestion2, null);
    manager.contributors = [contributor1, contributor2];
    int count = 0;
    bool done = false;
    AnalysisServer server = new AnalysisServerMock(searchEngine: searchEngine);
    CompletionRequest completionRequest =
        new CompletionRequestImpl(server, context, source, 0);
    manager.results(completionRequest).listen((CompletionResult r) {
      bool isLast = r is CompletionResultImpl ? r.isLast : true;
      switch (++count) {
        case 1:
          contributor1.assertCalls(context, source, 0, searchEngine);
          contributor2.assertCalls(context, source, 0, searchEngine);
          expect(isLast, isTrue);
          expect(r.suggestions, hasLength(2));
          expect(r.suggestions, contains(suggestion1));
          expect(r.suggestions, contains(suggestion2));
          break;
        default:
          fail('unexpected');
      }
    }, onDone: () {
      done = true;
      expect(count, equals(1));
    });
    return pumpEventQueue().then((_) {
      expect(done, isTrue);
    });
  }

  void _performAnalysis() {
    if (!_continuePerformingAnalysis) {
      return;
    }
    context.performAnalysisTask();
    new Future(_performAnalysis);
  }
}

class MockCompletionContributor extends DartCompletionContributor {
  final CompletionSuggestion fastSuggestion;
  final CompletionSuggestion fullSuggestion;
  int fastCount = 0;
  int fullCount = 0;
  DartCompletionRequest request;

  MockCompletionContributor(this.fastSuggestion, this.fullSuggestion);

  assertCalls(AnalysisContext context, Source source, int offset,
      SearchEngine searchEngine) {
    expect(request.context, equals(context));
    expect(request.source, equals(source));
    expect(request.offset, equals(offset));
    expect(request.searchEngine, equals(searchEngine));
    expect(this.fastCount, equals(1));
    expect(this.fullCount, equals(0));
  }

  assertFull(int fullCount) {
    expect(this.fastCount, equals(1));
    expect(this.fullCount, equals(fullCount));
  }

  @override
  bool computeFast(DartCompletionRequest request) {
    this.request = request;
    fastCount++;
    if (fastSuggestion != null) {
      request.addSuggestion(fastSuggestion);
    }
    return fastSuggestion != null;
  }

  @override
  Future<bool> computeFull(DartCompletionRequest request) {
    this.request = request;
    fullCount++;
    if (fullSuggestion != null) {
      request.addSuggestion(fullSuggestion);
    }
    return new Future.value(fullSuggestion != null);
  }
}
