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

// @dart = 2.9

import 'dart:async';

import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/completion_core.dart';
import 'package:analysis_server/src/services/completion/completion_performance.dart';
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
import 'package:analysis_server/src/services/completion/dart/imported_reference_contributor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'completion_contributor_util.dart';

void main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(CompletionManagerTest);
  });
}

@reflectiveTest
class CompletionManagerTest extends DartCompletionContributorTest {
  @override
  DartCompletionContributor createContributor() {
    return ImportedReferenceContributor();
  }

  Future<void> test_resolveDirectives() async {
    newFile('$testPackageLibPath/a.dart', content: '''
library libA;
/// My class.
/// Short description.
///
/// Longer description.
class A {}
''');
    newFile('$testPackageLibPath/b.dart', content: '''
library libB;
import "a.dart" as foo;
part 'test.dart';
''');
    addTestSource('part of libB; main() {^}');

    await resolveFile('$testPackageLibPath/b.dart');

    // Build the request
    var baseRequest = CompletionRequestImpl(
        await session.getResolvedUnit(testFile),
        completionOffset,
        CompletionPerformance());
    await baseRequest.performance.runRequestOperation((performance) async {
      var requestCompleter = Completer<DartCompletionRequest>();
      DartCompletionRequestImpl.from(
              performance, baseRequest, DartdocDirectiveInfo())
          .then((DartCompletionRequest request) {
        requestCompleter.complete(request);
      });
      request = await performAnalysis(200, requestCompleter);
    });

    var directives = request.target.unit.directives;

    var imports = request.libraryElement.imports;
    expect(imports, hasLength(directives.length + 1));

    ImportElement importNamed(String expectedUri) {
      var uriList = <String>[];
      for (var importElement in imports) {
        var uri = importElement.importedLibrary.source.uri.toString();
        uriList.add(uri);
        if (uri.endsWith(expectedUri)) {
          return importElement;
        }
      }
      fail('Failed to find $expectedUri in $uriList');
    }

    void assertImportedLib(String expectedUri) {
      var importElem = importNamed(expectedUri);
      expect(importElem.importedLibrary.exportNamespace, isNotNull);
    }

    // Assert that the new imports each have an export namespace
    assertImportedLib('dart:core');
    assertImportedLib('a.dart');
  }
}
