// 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.domain.completion;

import 'dart:async';

import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/channel/channel.dart';
import 'package:analysis_server/src/constants.dart';
import 'package:analysis_server/src/context_manager.dart';
import 'package:analysis_server/src/domain_analysis.dart';
import 'package:analysis_server/src/domain_completion.dart';
import 'package:analysis_server/src/plugin/server_plugin.dart';
import 'package:analysis_server/src/provisional/completion/completion_core.dart'
    show AnalysisRequest, CompletionRequest, CompletionResult;
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.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/completion/dart/contribution_sorter.dart';
import 'package:analysis_server/src/services/index/index.dart' show Index;
import 'package:analysis_server/src/services/index/local_memory_index.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/source/pub_package_map_provider.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:plugin/manager.dart';
import 'package:plugin/plugin.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unittest/unittest.dart';

import 'analysis_abstract.dart';
import 'domain_completion_util.dart';
import 'mock_sdk.dart';
import 'mocks.dart';
import 'utils.dart';

main() {
  initializeTestEnvironment();
  defineReflectiveTests(CompletionManagerTest);
  defineReflectiveTests(CompletionTest);
  defineReflectiveTests(_NoSearchEngine);
}

@reflectiveTest
class CompletionManagerTest extends AbstractAnalysisTest {
  AnalysisDomainHandler analysisDomain;
  Test_CompletionDomainHandler completionDomain;
  Request request;
  int requestCount = 0;
  String testFile2 = '/project/bin/test2.dart';

  AnalysisServer createAnalysisServer(Index index) {
    //
    // Collect plugins
    //
    ServerPlugin serverPlugin = new ServerPlugin();
    List<Plugin> plugins = <Plugin>[];
    plugins.addAll(AnalysisEngine.instance.requiredPlugins);
    plugins.add(serverPlugin);
    addServerPlugins(plugins);
    //
    // Process plugins
    //
    ExtensionManager manager = new ExtensionManager();
    manager.processPlugins(plugins);
    //
    // Create the server
    //
    return new Test_AnalysisServer(
        super.serverChannel,
        super.resourceProvider,
        super.packageMapProvider,
        index,
        serverPlugin,
        new AnalysisServerOptions(),
        new MockSdk(),
        InstrumentationService.NULL_SERVICE);
  }

  @override
  Index createIndex() {
    return createLocalMemoryIndex();
  }

  void sendRequest(String path) {
    String id = (++requestCount).toString();
    request = new CompletionGetSuggestionsParams(path, 0).toRequest(id);
    Response response = handler.handleRequest(request);
    expect(response, isResponseSuccess(id));
  }

  @override
  void setUp() {
    super.setUp();
    createProject();
    analysisDomain = handler;
    completionDomain = new Test_CompletionDomainHandler(server);
    handler = completionDomain;
    addTestFile('^library A; cl');
    addFile(testFile2, 'library B; cl');
  }

  void tearDown() {
    super.tearDown();
    analysisDomain = null;
    completionDomain = null;
  }

  /**
   * Assert different managers are used for different sources
   */
  test_2_requests_different_sources() {
    expect(completionDomain.manager, isNull);
    sendRequest(testFile);
    expect(completionDomain.manager, isNotNull);
    MockCompletionManager expectedManager = completionDomain.manager;
    expect(expectedManager.disposeCallCount, 0);
    expect(completionDomain.mockContext.mockStream.listenCount, 1);
    expect(completionDomain.mockContext.mockStream.cancelCount, 0);
    return pumpEventQueue().then((_) {
      expect(completionDomain.manager, expectedManager);
      expect(completionDomain.mockManager.computeCallCount, 1);
      sendRequest(testFile2);
      expect(completionDomain.manager, isNotNull);
      expect(completionDomain.manager, isNot(expectedManager));
      expect(expectedManager.disposeCallCount, 1);
      expectedManager = completionDomain.manager;
      expect(completionDomain.mockContext.mockStream.listenCount, 2);
      expect(completionDomain.mockContext.mockStream.cancelCount, 1);
      return pumpEventQueue();
    }).then((_) {
      expect(completionDomain.manager, expectedManager);
      expect(completionDomain.mockContext.mockStream.listenCount, 2);
      expect(completionDomain.mockContext.mockStream.cancelCount, 1);
      expect(completionDomain.mockManager.computeCallCount, 1);
    });
  }

  /**
   * Assert same manager is used for multiple requests on same source
   */
  test_2_requests_same_source() {
    expect(completionDomain.manager, isNull);
    sendRequest(testFile);
    expect(completionDomain.manager, isNotNull);
    expect(completionDomain.manager.source, isNotNull);
    CompletionManager expectedManager = completionDomain.manager;
    expect(completionDomain.mockContext.mockStream.listenCount, 1);
    expect(completionDomain.mockContext.mockStream.cancelCount, 0);
    return pumpEventQueue().then((_) {
      expect(completionDomain.manager, expectedManager);
      expect(completionDomain.mockManager.computeCallCount, 1);
      sendRequest(testFile);
      expect(completionDomain.manager, expectedManager);
      expect(completionDomain.mockContext.mockStream.listenCount, 1);
      expect(completionDomain.mockContext.mockStream.cancelCount, 0);
      return pumpEventQueue();
    }).then((_) {
      expect(completionDomain.manager, expectedManager);
      expect(completionDomain.mockContext.mockStream.listenCount, 1);
      expect(completionDomain.mockContext.mockStream.cancelCount, 0);
      expect(completionDomain.mockManager.computeCallCount, 2);
    });
  }

  /**
   * Assert manager is NOT cleared when context NOT associated with manager changes.
   */
  test_contextsChanged_different() {
    sendRequest(testFile);
    CompletionManager expectedManager;
    return pumpEventQueue().then((_) {
      expect(completionDomain.manager, isNotNull);
      expectedManager = completionDomain.manager;
      completionDomain.contextsChangedRaw(
          new ContextsChangedEvent(changed: [new MockContext()]));
      return pumpEventQueue();
    }).then((_) {
      expect(completionDomain.manager, expectedManager);
    });
  }

  /**
   * Assert manager is cleared when context associated with manager changes.
   */
  test_contextsChanged_same() {
    sendRequest(testFile);
    return pumpEventQueue().then((_) {
      expect(completionDomain.manager, isNotNull);
      completionDomain.contextsChangedRaw(
          new ContextsChangedEvent(changed: [completionDomain.mockContext]));
      return pumpEventQueue();
    }).then((_) {
      expect(completionDomain.manager, isNull);
    });
  }

  /**
   * Assert manager is cleared when analysis roots are set
   */
  test_setAnalysisRoots() {
    sendRequest(testFile);
    return pumpEventQueue().then((_) {
      expect(completionDomain.manager, isNotNull);
      request = new AnalysisSetAnalysisRootsParams([], []).toRequest('7');
      Response response = analysisDomain.handleRequest(request);
      expect(response, isResponseSuccess('7'));
      return pumpEventQueue();
    }).then((_) {
      expect(completionDomain.manager, isNull);
    });
  }

  /**
   * Assert manager is cleared when source NOT associated with manager is changed.
   */
  test_sourcesChanged_different_source_changed() {
    sendRequest(testFile);
    return pumpEventQueue().then((_) {
      expect(completionDomain.manager, isNotNull);
      ContextSourcePair contextSource = server.getContextSourcePair(testFile2);
      ChangeSet changeSet = new ChangeSet();
      changeSet.changedSource(contextSource.source);
      completionDomain.sourcesChanged(new SourcesChangedEvent(changeSet));
      expect(completionDomain.manager, isNull);
    });
  }

  /**
   * Assert manager is NOT cleared when source associated with manager is changed.
   */
  test_sourcesChanged_same_source_changed() {
    sendRequest(testFile);
    return pumpEventQueue().then((_) {
      expect(completionDomain.manager, isNotNull);
      CompletionManager expectedManager = completionDomain.manager;
      ChangeSet changeSet = new ChangeSet();
      changeSet.changedSource(completionDomain.manager.source);
      completionDomain.sourcesChanged(new SourcesChangedEvent(changeSet));
      expect(completionDomain.manager, expectedManager);
    });
  }

  /**
   * Assert manager is cleared when source is deleted
   */
  test_sourcesChanged_source_deleted() {
    sendRequest(testFile);
    return pumpEventQueue().then((_) {
      expect(completionDomain.manager, isNotNull);
      ChangeSet changeSet = new ChangeSet();
      changeSet.deletedSource(completionDomain.manager.source);
      completionDomain.sourcesChanged(new SourcesChangedEvent(changeSet));
      expect(completionDomain.manager, isNull);
    });
  }

  /**
   * Assert manager is cleared when source is removed
   */
  test_sourcesChanged_source_removed() {
    sendRequest(testFile);
    return pumpEventQueue().then((_) {
      expect(completionDomain.manager, isNotNull);
      ChangeSet changeSet = new ChangeSet();
      changeSet.removedSource(completionDomain.manager.source);
      completionDomain.sourcesChanged(new SourcesChangedEvent(changeSet));
      expect(completionDomain.manager, isNull);
    });
  }
}

@reflectiveTest
class CompletionTest extends AbstractCompletionDomainTest {
  test_html() {
    testFile = '/project/web/test.html';
    addTestFile('''
      <html>^</html>
    ''');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      expect(suggestions, hasLength(0));
    });
  }

  test_imports() {
    addTestFile('''
      import 'dart:html';
      main() {^}
    ''');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object');
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'HtmlElement');
      assertNoResult('test');
    });
  }

  test_imports_incremental() async {
    addTestFile('''library foo;
      e^
      import "dart:async";
      import "package:foo/foo.dart";
      class foo { }''');
    await waitForTasksFinished();
    server.updateContent('uc1', {testFile: new AddContentOverlay(testCode)});
    server.updateContent('uc2', {
      testFile:
          new ChangeContentOverlay([new SourceEdit(completionOffset, 0, 'xp')])
    });
    completionOffset += 2;
    await getSuggestions();
    expect(replacementOffset, completionOffset - 3);
    expect(replacementLength, 3);
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'export',
        relevance: DART_RELEVANCE_HIGH);
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'import',
        relevance: DART_RELEVANCE_HIGH);
    assertNoResult('extends');
    assertNoResult('library');
  }

  test_imports_partial() async {
    addTestFile('''^
      import "package:foo/foo.dart";
      import "package:bar/bar.dart";
      class Baz { }''');

    // Wait for analysis then edit the content
    await waitForTasksFinished();
    String revisedContent = testCode.substring(0, completionOffset) +
        'i' +
        testCode.substring(completionOffset);
    ++completionOffset;
    server.handleRequest(new AnalysisUpdateContentParams(
        {testFile: new AddContentOverlay(revisedContent)}).toRequest('add1'));

    // Request code completion immediately after edit
    Response response = handleSuccessfulRequest(
        new CompletionGetSuggestionsParams(testFile, completionOffset)
            .toRequest('0'));
    completionId = response.id;
    assertValidId(completionId);
    await waitForTasksFinished();
    expect(replacementOffset, completionOffset - 1);
    expect(replacementLength, 1);
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'library',
        relevance: DART_RELEVANCE_HIGH);
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'import',
        relevance: DART_RELEVANCE_HIGH);
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'export',
        relevance: DART_RELEVANCE_HIGH);
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'part',
        relevance: DART_RELEVANCE_HIGH);
    assertNoResult('extends');
  }

  test_imports_prefixed() {
    addTestFile('''
      import 'dart:html' as foo;
      main() {^}
    ''');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object');
      assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'foo');
      assertNoResult('HtmlElement');
      assertNoResult('test');
    });
  }

  test_imports_prefixed2() {
    addTestFile('''
      import 'dart:html' as foo;
      main() {foo.^}
    ''');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'HtmlElement');
      assertNoResult('test');
    });
  }

  test_invocation() {
    addTestFile('class A {b() {}} main() {A a; a.^}');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'b');
    });
  }

  test_invocation_sdk_relevancy_off() {
    var originalSorter = DartCompletionManager.contributionSorter;
    var mockSorter = new MockRelevancySorter();
    DartCompletionManager.contributionSorter = mockSorter;
    addTestFile('main() {Map m; m.^}');
    return getSuggestions().then((_) {
      // Assert that the CommonUsageComputer has been replaced
      expect(suggestions.any((s) => s.relevance == DART_RELEVANCE_COMMON_USAGE),
          isFalse);
      DartCompletionManager.contributionSorter = originalSorter;
      mockSorter.enabled = false;
    });
  }

  test_invocation_sdk_relevancy_on() {
    addTestFile('main() {Map m; m.^}');
    return getSuggestions().then((_) {
      // Assert that the CommonUsageComputer is working
      expect(suggestions.any((s) => s.relevance == DART_RELEVANCE_COMMON_USAGE),
          isTrue);
    });
  }

  test_invocation_withTrailingStmt() {
    addTestFile('class A {b() {}} main() {A a; a.^ int x = 7;}');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'b');
    });
  }

  test_inComment_block_beforeNode() async {
    addTestFile('''
  main(aaa, bbb) {
    /* text ^ */
    print(42);
  }
  ''');
    await getSuggestions();
    expect(suggestions, isEmpty);
  }

  test_inComment_endOfLine_beforeNode() async {
    addTestFile('''
  main(aaa, bbb) {
    // text ^
    print(42);
  }
  ''');
    await getSuggestions();
    expect(suggestions, isEmpty);
  }

  test_inComment_endOfLine_beforeToken() async {
    addTestFile('''
  main(aaa, bbb) {
    // text ^
  }
  ''');
    await getSuggestions();
    expect(suggestions, isEmpty);
  }

  test_inDartDoc1() async {
    addTestFile('''
  /// ^
  main(aaa, bbb) {}
  ''');
    await getSuggestions();
    expect(suggestions, isEmpty);
  }

  test_inDartDoc2() async {
    addTestFile('''
  /// Some text^
  main(aaa, bbb) {}
  ''');
    await getSuggestions();
    expect(suggestions, isEmpty);
  }

  test_inDartDoc_reference1() async {
    addFile(
        '/testA.dart',
        '''
  part of libA;
  foo(bar) => 0;''');
    addTestFile('''
  library libA;
  part "/testA.dart";
  import "dart:math";
  /// The [^]
  main(aaa, bbb) {}
  ''');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'main',
        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
    assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'foo',
        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
    assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'min');
  }

  test_inDartDoc_reference2() async {
    addTestFile('''
  /// The [m^]
  main(aaa, bbb) {}
  ''');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'main',
        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
  }

  test_inherited() {
    addFile('/libA.dart', 'class A {m() {}}');
    addTestFile('''
import '/libA.dart';
class B extends A {
  x() {^}
}
''');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm');
    });
  }

  test_keyword() {
    addTestFile('library A; cl^');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset - 2));
      expect(replacementLength, equals(2));
      assertHasResult(CompletionSuggestionKind.KEYWORD, 'export',
          relevance: DART_RELEVANCE_HIGH);
      assertHasResult(CompletionSuggestionKind.KEYWORD, 'class',
          relevance: DART_RELEVANCE_HIGH);
    });
  }

  test_local_named_constructor() {
    addTestFile('class A {A.c(); x() {new A.^}}');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'c');
      assertNoResult('A');
    });
  }

  test_local_override() {
    addFile('/libA.dart', 'class A {m() {}}');
    addTestFile('''
import '/libA.dart';
class B extends A {
  m() {}
  x() {^}
}
''');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm',
          relevance: DART_RELEVANCE_LOCAL_METHOD);
    });
  }

  test_locals() {
    addTestFile('class A {var a; x() {var b;^}} class DateTime { }');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'A');
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'a',
          relevance: DART_RELEVANCE_LOCAL_FIELD);
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'b',
          relevance: DART_RELEVANCE_LOCAL_VARIABLE);
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'x',
          relevance: DART_RELEVANCE_LOCAL_METHOD);
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'DateTime');
    });
  }

  test_offset_past_eof() {
    addTestFile('main() { }', offset: 300);
    Request request =
        new CompletionGetSuggestionsParams(testFile, completionOffset)
            .toRequest('0');
    Response response = handler.handleRequest(request);
    expect(response.id, '0');
    expect(response.error.code, RequestErrorCode.INVALID_PARAMETER);
  }

  test_overrides() {
    addFile('/libA.dart', 'class A {m() {}}');
    addTestFile('''
import '/libA.dart';
class B extends A {m() {^}}
''');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm',
          relevance: DART_RELEVANCE_LOCAL_METHOD);
    });
  }

  test_partFile() {
    addFile(
        '/project/bin/testA.dart',
        '''
      library libA;
      part "$testFile";
      import 'dart:html';
      class A { }
    ''');
    addTestFile('''
      part of libA;
      main() {^}''');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object');
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'HtmlElement');
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'A');
      assertNoResult('test');
    });
  }

  test_partFile2() {
    addFile(
        '/testA.dart',
        '''
      part of libA;
      class A { }''');
    addTestFile('''
      library libA;
      part "/testA.dart";
      import 'dart:html';
      main() {^}
    ''');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object');
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'HtmlElement');
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'A');
      assertNoResult('test');
    });
  }

  test_simple() {
    addTestFile('''
      void main() {
        ^
      }
    ''');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object');
      assertNoResult('HtmlElement');
      assertNoResult('test');
    });
  }

  test_static() {
    addTestFile('class A {static b() {} c() {}} main() {A.^}');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'b');
      assertNoResult('c');
    });
  }

  test_topLevel() {
    addTestFile('''
      typedef foo();
      var test = '';
      main() {tes^t}
    ''');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset - 3));
      expect(replacementLength, equals(4));
      // Suggestions based upon imported elements are partially filtered
      //assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object');
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'test',
          relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
      assertNoResult('HtmlElement');
    });
  }
}

class MockCompletionManager implements CompletionManager {
  final AnalysisContext context;
  final Source source;
  final SearchEngine searchEngine;
  StreamController<CompletionResult> controller;
  int computeCallCount = 0;
  int disposeCallCount = 0;

  MockCompletionManager(this.context, this.source, this.searchEngine);

  @override
  Future<bool> computeCache() {
    return new Future.value(true);
  }

  @override
  void computeSuggestions(CompletionRequest request) {
    ++computeCallCount;
    CompletionResult result = new CompletionResultImpl(0, 0, [], true);
    controller.add(result);
  }

  @override
  void dispose() {
    ++disposeCallCount;
  }

  @override
  Stream<CompletionResult> results(CompletionRequest request) {
    controller = new StreamController<CompletionResult>(onListen: () {
      scheduleMicrotask(() {
        computeSuggestions(request);
      });
    });
    return controller.stream;
  }
}

/**
 * Mock [AnaysisContext] for tracking usage of onSourcesChanged.
 */
class MockContext implements AnalysisContext {
  static final SourceFactory DEFAULT_SOURCE_FACTORY = new SourceFactory([]);

  MockStream<SourcesChangedEvent> mockStream;

  SourceFactory sourceFactory = DEFAULT_SOURCE_FACTORY;

  MockContext() {
    mockStream = new MockStream<SourcesChangedEvent>();
  }

  @override
  Stream<SourcesChangedEvent> get onSourcesChanged => mockStream;

  @override
  bool exists(Source source) {
    return source != null && source.exists();
  }

  @override
  TimestampedData<String> getContents(Source source) {
    return source.contents;
  }

  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}

class MockRelevancySorter implements DartContributionSorter {
  bool enabled = true;

  @override
  Future sort(
      CompletionRequest request, Iterable<CompletionSuggestion> suggestions) {
    if (!enabled) {
      throw 'unexpected sort';
    }
    return new Future.value();
  }
}

/**
 * Mock stream for tracking calls to listen and subscription.cancel.
 */
class MockStream<E> implements Stream<E> {
  MockSubscription<E> mockSubscription = new MockSubscription<E>();
  int listenCount = 0;

  int get cancelCount => mockSubscription.cancelCount;

  @override
  StreamSubscription<E> listen(void onData(E event),
      {Function onError, void onDone(), bool cancelOnError}) {
    ++listenCount;
    return mockSubscription;
  }

  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}

/**
 * Mock subscription for tracking calls to subscription.cancel.
 */
class MockSubscription<E> implements StreamSubscription<E> {
  int cancelCount = 0;

  Future cancel() {
    ++cancelCount;
    return new Future.value(true);
  }

  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}

class Test_AnalysisServer extends AnalysisServer {
  final MockContext mockContext = new MockContext();

  Test_AnalysisServer(
      ServerCommunicationChannel channel,
      ResourceProvider resourceProvider,
      PubPackageMapProvider packageMapProvider,
      Index index,
      ServerPlugin serverPlugin,
      AnalysisServerOptions analysisServerOptions,
      DartSdk defaultSdk,
      InstrumentationService instrumentationService)
      : super(
            channel,
            resourceProvider,
            packageMapProvider,
            index,
            serverPlugin,
            analysisServerOptions,
            defaultSdk,
            instrumentationService);

  @override
  AnalysisContext getAnalysisContext(String path) {
    return mockContext;
  }

  @override
  ContextSourcePair getContextSourcePair(String path) {
    ContextSourcePair pair = super.getContextSourcePair(path);
    return new ContextSourcePair(mockContext, pair.source);
  }
}

/**
 * A [CompletionDomainHandler] subclass that returns a mock completion manager
 * so that the domain handler cache management can be tested.
 */
class Test_CompletionDomainHandler extends CompletionDomainHandler {
  Test_CompletionDomainHandler(Test_AnalysisServer server) : super(server);

  MockContext get mockContext => (server as Test_AnalysisServer).mockContext;

  MockCompletionManager get mockManager => manager;

  void contextsChanged(ContextsChangedEvent event) {
    contextsChangedRaw(new ContextsChangedEvent(
        added: event.added.length > 0 ? [mockContext] : [],
        changed: event.changed.length > 0 ? [mockContext] : [],
        removed: event.removed.length > 0 ? [mockContext] : []));
  }

  void contextsChangedRaw(ContextsChangedEvent newEvent) {
    super.contextsChanged(newEvent);
  }

  CompletionManager createCompletionManager(
      AnalysisServer server, AnalysisContext context, Source source) {
    return new MockCompletionManager(mockContext, source, searchEngine);
  }
}

@reflectiveTest
class _NoSearchEngine extends AbstractAnalysisTest {
  @override
  void setUp() {
    super.setUp();
    createProject();
    handler = new CompletionDomainHandler(server);
  }

  test_noSearchEngine() async {
    addTestFile('''
main() {
  ^
}
    ''');
    await waitForTasksFinished();
    Request request =
        new CompletionGetSuggestionsParams(testFile, 0).toRequest('0');
    Response response = handler.handleRequest(request);
    expect(response.error, isNotNull);
    expect(response.error.code, RequestErrorCode.NO_INDEX_GENERATED);
  }
}
