// Copyright (c) 2016, 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 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/pub_summary.dart';
import 'package:analyzer/src/summary/summarize_elements.dart';
import 'package:path/path.dart' as pathos;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../context/abstract_context.dart';
import '../context/mock_sdk.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(PubSummaryManagerTest);
  });
}

@reflectiveTest
class PubSummaryManagerTest extends AbstractContextTest {
  /**
   * The path to the root of the pubcache directory used in these tests. The
   * path has not been converted to the current platform, and is therefore only
   * appropriate for composing paths that will later be converted.
   */
  static const String CACHE = '/home/.pub-cache/hosted/pub.dartlang.org';

  PubSummaryManager manager;

  Folder getFolder(String path) =>
      resourceProvider.getFolder(resourceProvider.convertPath(path));

  File newFile(String path, String content) {
    //, [int stamp]) {
    return resourceProvider.newFile(
        resourceProvider.convertPath(path), content);
  }

  Folder newFolder(String path) =>
      resourceProvider.newFolder(resourceProvider.convertPath(path));

  void setUp() {
    super.setUp();
    _createManager();
  }

  test_computeUnlinkedForFolder() async {
    // Create package files.
    newFile(
        '/flutter/aaa/lib/a.dart',
        '''
class A {}
''');
    newFile(
        '/flutter/bbb/lib/b.dart',
        '''
class B {}
''');

    // Configure packages resolution.
    Folder libFolderA = newFolder('/flutter/aaa/lib');
    Folder libFolderB = newFolder('/flutter/bbb/lib');
    context.sourceFactory = new SourceFactory(<UriResolver>[
      sdkResolver,
      resourceResolver,
      new PackageMapUriResolver(resourceProvider, {
        'aaa': [libFolderA],
        'bbb': [libFolderB],
      })
    ]);

    await manager.computeUnlinkedForFolder('aaa', libFolderA);
    await manager.computeUnlinkedForFolder('bbb', libFolderB);

    // The files must be created.
    _assertFileExists(libFolderA.parent, PubSummaryManager.UNLINKED_NAME);
    _assertFileExists(libFolderA.parent, PubSummaryManager.UNLINKED_SPEC_NAME);
    _assertFileExists(libFolderB.parent, PubSummaryManager.UNLINKED_NAME);
    _assertFileExists(libFolderB.parent, PubSummaryManager.UNLINKED_SPEC_NAME);
  }

  test_getLinkedBundles_cached() async {
    String pathA1 = '$CACHE/aaa-1.0.0';
    String pathA2 = '$CACHE/aaa-2.0.0';
    newFile(
        '$pathA1/lib/a.dart',
        '''
class A {}
int a;
''');
    newFile(
        '$pathA2/lib/a.dart',
        '''
class A2 {}
int a;
''');
    newFile(
        '$CACHE/bbb/lib/b.dart',
        '''
import 'package:aaa/a.dart';
A b;
''');
    Folder folderA1 = getFolder(pathA1);
    Folder folderA2 = getFolder(pathA2);
    Folder folderB = getFolder('$CACHE/bbb');

    // Configure packages resolution.
    Folder libFolderA1 = newFolder('$pathA1/lib');
    Folder libFolderA2 = newFolder('$pathA2/lib');
    Folder libFolderB = newFolder('$CACHE/bbb/lib');
    context.sourceFactory = new SourceFactory(<UriResolver>[
      sdkResolver,
      resourceResolver,
      new PackageMapUriResolver(resourceProvider, {
        'aaa': [libFolderA1],
        'bbb': [libFolderB],
      })
    ]);

    // Session 1.
    // Create linked bundles and store them in files.
    String linkedHashA;
    String linkedHashB;
    {
      // Ensure unlinked bundles.
      manager.getUnlinkedBundles(context);
      await manager.onUnlinkedComplete;

      // Now we should be able to get linked bundles.
      List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
      expect(linkedPackages, hasLength(2));

      // Verify that files with linked bundles were created.
      LinkedPubPackage packageA = _getLinkedPackage(linkedPackages, 'aaa');
      LinkedPubPackage packageB = _getLinkedPackage(linkedPackages, 'bbb');
      linkedHashA = packageA.linkedHash;
      linkedHashB = packageB.linkedHash;
      _assertFileExists(folderA1, 'linked_spec_$linkedHashA.ds');
      _assertFileExists(folderB, 'linked_spec_$linkedHashB.ds');
    }

    // Session 2.
    // Recreate manager and ask again.
    {
      _createManager();
      List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
      expect(linkedPackages, hasLength(2));

      // Verify that linked packages have the same hashes, so they must
      // be have been read from the previously created files.
      LinkedPubPackage packageA = _getLinkedPackage(linkedPackages, 'aaa');
      LinkedPubPackage packageB = _getLinkedPackage(linkedPackages, 'bbb');
      expect(packageA.linkedHash, linkedHashA);
      expect(packageB.linkedHash, linkedHashB);
    }

    // Session 2 with different 'aaa' version.
    // Different linked bundles.
    {
      context.sourceFactory = new SourceFactory(<UriResolver>[
        sdkResolver,
        resourceResolver,
        new PackageMapUriResolver(resourceProvider, {
          'aaa': [libFolderA2],
          'bbb': [libFolderB],
        })
      ]);

      // Ensure unlinked bundles.
      manager.getUnlinkedBundles(context);
      await manager.onUnlinkedComplete;

      // Now we should be able to get linked bundles.
      List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
      expect(linkedPackages, hasLength(2));

      // Verify that new files with linked bundles were created.
      LinkedPubPackage packageA = _getLinkedPackage(linkedPackages, 'aaa');
      LinkedPubPackage packageB = _getLinkedPackage(linkedPackages, 'bbb');
      expect(packageA.linkedHash, isNot(linkedHashA));
      expect(packageB.linkedHash, isNot(linkedHashB));
      _assertFileExists(folderA2, 'linked_spec_${packageA.linkedHash}.ds');
      _assertFileExists(folderB, 'linked_spec_${packageB.linkedHash}.ds');
    }
  }

  test_getLinkedBundles_cached_declaredVariables_export() async {
    await _testImpl_getLinkedBundles_cached_declaredVariables('export');
  }

  test_getLinkedBundles_cached_declaredVariables_import() async {
    await _testImpl_getLinkedBundles_cached_declaredVariables('import');
  }

  test_getLinkedBundles_cached_differentSdk() async {
    String pathA = '$CACHE/aaa';
    newFile(
        '$pathA/lib/a.dart',
        '''
class A {}
int a;
''');
    newFile(
        '$CACHE/bbb/lib/b.dart',
        '''
import 'package:aaa/a.dart';
A b;
''');
    Folder folderA = getFolder(pathA);
    Folder folderB = getFolder('$CACHE/bbb');

    // Configure packages resolution.
    Folder libFolderA = newFolder('$pathA/lib');
    Folder libFolderB = newFolder('$CACHE/bbb/lib');
    context.sourceFactory = new SourceFactory(<UriResolver>[
      sdkResolver,
      resourceResolver,
      new PackageMapUriResolver(resourceProvider, {
        'aaa': [libFolderA],
        'bbb': [libFolderB],
      })
    ]);

    // Session 1.
    // Create linked bundles and store them in files.
    String linkedHashA;
    String linkedHashB;
    {
      // Ensure unlinked bundles.
      manager.getUnlinkedBundles(context);
      await manager.onUnlinkedComplete;

      // Now we should be able to get linked bundles.
      List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
      expect(linkedPackages, hasLength(2));

      // Verify that files with linked bundles were created.
      LinkedPubPackage packageA = _getLinkedPackage(linkedPackages, 'aaa');
      LinkedPubPackage packageB = _getLinkedPackage(linkedPackages, 'bbb');
      linkedHashA = packageA.linkedHash;
      linkedHashB = packageB.linkedHash;
      _assertFileExists(folderA, 'linked_spec_$linkedHashA.ds');
      _assertFileExists(folderB, 'linked_spec_$linkedHashB.ds');
    }

    // Session 2.
    // Use DartSdk with a different API signature.
    // Different linked bundles should be created.
    {
      MockSdk sdk = new MockSdk(resourceProvider: resourceProvider);
      sdk.updateUriFile('dart:math', (String content) {
        return content + '  class NewMathClass {}';
      });
      context.sourceFactory = new SourceFactory(<UriResolver>[
        new DartUriResolver(sdk),
        resourceResolver,
        new PackageMapUriResolver(resourceProvider, {
          'aaa': [libFolderA],
          'bbb': [libFolderB],
        })
      ]);

      // Ensure unlinked bundles.
      manager.getUnlinkedBundles(context);
      await manager.onUnlinkedComplete;

      // Now we should be able to get linked bundles.
      List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
      expect(linkedPackages, hasLength(2));

      // Verify that new files with linked bundles were created.
      LinkedPubPackage packageA = _getLinkedPackage(linkedPackages, 'aaa');
      LinkedPubPackage packageB = _getLinkedPackage(linkedPackages, 'bbb');
      expect(packageA.linkedHash, isNot(linkedHashA));
      expect(packageB.linkedHash, isNot(linkedHashB));
      _assertFileExists(folderA, 'linked_spec_${packageA.linkedHash}.ds');
      _assertFileExists(folderB, 'linked_spec_${packageB.linkedHash}.ds');
    }
  }

  test_getLinkedBundles_cached_inconsistent_majorVersion() async {
    String pathA = '$CACHE/aaa';
    newFile(
        '$pathA/lib/a.dart',
        '''
class A {}
int a;
''');
    // Configure packages resolution.
    Folder libFolderA = newFolder('$pathA/lib');
    context.sourceFactory = new SourceFactory(<UriResolver>[
      sdkResolver,
      resourceResolver,
      new PackageMapUriResolver(resourceProvider, {
        'aaa': [libFolderA],
      })
    ]);

    // Session 1.
    // Create the linked bundle and cache it in a file.
    {
      // Ensure unlinked bundles.
      manager.getUnlinkedBundles(context);
      await manager.onUnlinkedComplete;

      // Now we should be able to get the linked bundle.
      List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
      expect(linkedPackages, hasLength(1));
    }

    // Session 2.
    // Recreate manager with a different major version.
    // It cannot use the previously cache linked bundle.
    // The reason is that we cannot use the cached unlinked bundle.
    {
      _createManager(majorVersion: 12345);
      List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
      expect(linkedPackages, isEmpty);
    }
  }

  test_getLinkedBundles_hasCycle() async {
    newFile(
        '$CACHE/aaa/lib/a.dart',
        '''
import 'package:bbb/b.dart';
class A {}
int a1;
B a2;
''');
    newFile(
        '$CACHE/bbb/lib/b.dart',
        '''
import 'package:ccc/c.dart';
class B {}
C b;
''');
    newFile(
        '$CACHE/ccc/lib/c.dart',
        '''
import 'package:aaa/a.dart';
import 'package:ddd/d.dart';
class C {}
A c1;
D c2;
''');
    newFile(
        '$CACHE/ddd/lib/d.dart',
        '''
class D {}
String d;
''');

    // Configure packages resolution.
    Folder libFolderA = newFolder('$CACHE/aaa/lib');
    Folder libFolderB = newFolder('$CACHE/bbb/lib');
    Folder libFolderC = newFolder('$CACHE/ccc/lib');
    Folder libFolderD = newFolder('$CACHE/ddd/lib');
    context.sourceFactory = new SourceFactory(<UriResolver>[
      sdkResolver,
      resourceResolver,
      new PackageMapUriResolver(resourceProvider, {
        'aaa': [libFolderA],
        'bbb': [libFolderB],
        'ccc': [libFolderC],
        'ddd': [libFolderD],
      })
    ]);

    // Ensure unlinked bundles.
    manager.getUnlinkedBundles(context);
    await manager.onUnlinkedComplete;

    // Now we should be able to get linked bundles.
    List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
    expect(linkedPackages, hasLength(4));

    // package:aaa
    {
      LinkedPubPackage linkedPackage = linkedPackages
          .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa');
      expect(linkedPackage.linked.linkedLibraryUris, ['package:aaa/a.dart']);
      _assertHasLinkedVariable(linkedPackage, 'a1', 'int',
          expectedTypeNameUri: 'dart:core');
      _assertHasLinkedVariable(linkedPackage, 'a2', 'B',
          expectedTypeNameUri: 'package:bbb/b.dart');
    }

    // package:bbb
    {
      LinkedPubPackage linkedPackage = linkedPackages
          .singleWhere((linkedPackage) => linkedPackage.package.name == 'bbb');
      expect(linkedPackage.linked.linkedLibraryUris, ['package:bbb/b.dart']);
      _assertHasLinkedVariable(linkedPackage, 'b', 'C',
          expectedTypeNameUri: 'package:ccc/c.dart');
    }

    // package:ccc
    {
      LinkedPubPackage linkedPackage = linkedPackages
          .singleWhere((linkedPackage) => linkedPackage.package.name == 'ccc');
      expect(linkedPackage.linked.linkedLibraryUris, ['package:ccc/c.dart']);
      _assertHasLinkedVariable(linkedPackage, 'c1', 'A',
          expectedTypeNameUri: 'package:aaa/a.dart');
      _assertHasLinkedVariable(linkedPackage, 'c2', 'D',
          expectedTypeNameUri: 'package:ddd/d.dart');
    }

    // package:ddd
    {
      LinkedPubPackage linkedPackage = linkedPackages
          .singleWhere((linkedPackage) => linkedPackage.package.name == 'ddd');
      expect(linkedPackage.linked.linkedLibraryUris, ['package:ddd/d.dart']);
      _assertHasLinkedVariable(linkedPackage, 'd', 'String',
          expectedTypeNameUri: 'dart:core');
    }
  }

  test_getLinkedBundles_missingBundle_listed() async {
    newFile(
        '$CACHE/aaa/lib/a.dart',
        '''
import 'package:bbb/b.dart';
B a;
''');
    newFile(
        '$CACHE/bbb/lib/b.dart',
        '''
class B {}
''');

    // Configure packages resolution.
    Folder libFolderA = newFolder('$CACHE/aaa/lib');
    Folder libFolderB = newFolder('$CACHE/bbb/lib');
    context.sourceFactory = new SourceFactory(<UriResolver>[
      sdkResolver,
      resourceResolver,
      new PackageMapUriResolver(resourceProvider, {
        'aaa': [libFolderA],
        'bbb': [libFolderB],
      })
    ]);

    // Ensure unlinked bundles for 'aaa'.
    await manager.computeUnlinkedForFolder('aaa', libFolderA);

    // Try to link.
    // Neither 'aaa' nor 'bbb' are linked.
    // 'bbb' does not have the unlinked bundle.
    // 'aaa' is not linked because it references 'bbb', which is listed.
    List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
    expect(linkedPackages, hasLength(0));
  }

  test_getLinkedBundles_missingBundle_listed_chained() async {
    newFile(
        '$CACHE/aaa/lib/a.dart',
        '''
import 'package:bbb/b.dart';
''');
    newFile(
        '$CACHE/bbb/lib/b.dart',
        '''
import 'package:ccc/c.dart';
''');
    newFile(
        '$CACHE/ccc/lib/c.dart',
        '''
class C {}
''');

    // Configure packages resolution.
    Folder libFolderA = newFolder('$CACHE/aaa/lib');
    Folder libFolderB = newFolder('$CACHE/bbb/lib');
    Folder libFolderC = newFolder('$CACHE/ccc/lib');
    context.sourceFactory = new SourceFactory(<UriResolver>[
      sdkResolver,
      resourceResolver,
      new PackageMapUriResolver(resourceProvider, {
        'aaa': [libFolderA],
        'bbb': [libFolderB],
        'ccc': [libFolderC],
      })
    ]);

    // Ensure unlinked bundles.
    await manager.computeUnlinkedForFolder('aaa', libFolderA);
    await manager.computeUnlinkedForFolder('bbb', libFolderB);

    // Try to link.
    // Neither 'aaa' nor 'bbb' are linked.
    // 'ccc' is listed in the package map, but its unlinked bundle is not ready.
    List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
    expect(linkedPackages, hasLength(0));
  }

  test_getLinkedBundles_missingBundle_listed_partial() async {
    newFile(
        '$CACHE/aaa/lib/a.dart',
        '''
int a;
''');
    newFile(
        '$CACHE/bbb/lib/b.dart',
        '''
import 'package:ccc/c.dart';
C b;
''');
    newFile(
        '$CACHE/ccc/lib/c.dart',
        '''
class C {}
''');

    // Configure packages resolution.
    Folder libFolderA = newFolder('$CACHE/aaa/lib');
    Folder libFolderB = newFolder('$CACHE/bbb/lib');
    Folder libFolderC = newFolder('$CACHE/ccc/lib');
    context.sourceFactory = new SourceFactory(<UriResolver>[
      sdkResolver,
      resourceResolver,
      new PackageMapUriResolver(resourceProvider, {
        'aaa': [libFolderA],
        'bbb': [libFolderB],
        'ccc': [libFolderC],
      })
    ]);

    // Ensure unlinked bundles for 'aaa'.
    await manager.computeUnlinkedForFolder('aaa', libFolderA);
    await manager.computeUnlinkedForFolder('bbb', libFolderB);

    // Try to link.
    // Only 'aaa' is linked.
    // The package 'bbb' references the listed 'ccc' without unlinked bundle.
    List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
    expect(linkedPackages, hasLength(1));

    // package:aaa
    {
      LinkedPubPackage linkedPackage = linkedPackages
          .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa');
      _assertHasLinkedVariable(linkedPackage, 'a', 'int',
          expectedTypeNameUri: 'dart:core');
    }
  }

  test_getLinkedBundles_missingBundle_notListed() async {
    newFile(
        '$CACHE/aaa/lib/a.dart',
        '''
int a;
''');
    newFile(
        '$CACHE/bbb/lib/b.dart',
        '''
import 'package:ccc/c.dart';
int b1;
C b2;
''');

    // Configure packages resolution.
    Folder libFolderA = newFolder('$CACHE/aaa/lib');
    Folder libFolderB = newFolder('$CACHE/bbb/lib');
    context.sourceFactory = new SourceFactory(<UriResolver>[
      sdkResolver,
      resourceResolver,
      new PackageMapUriResolver(resourceProvider, {
        'aaa': [libFolderA],
        'bbb': [libFolderB],
      })
    ]);

    // Ensure unlinked bundles.
    manager.getUnlinkedBundles(context);
    await manager.onUnlinkedComplete;

    // Try to link.
    // Both 'aaa' and 'bbb' are linked.
    // The package 'ccc' is not listed, so it cannot be resolved anyway,
    // with summaries or without them.
    List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
    expect(linkedPackages, hasLength(2));

    // package:aaa
    {
      LinkedPubPackage linkedPackage = linkedPackages
          .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa');
      _assertHasLinkedVariable(linkedPackage, 'a', 'int',
          expectedTypeNameUri: 'dart:core');
    }

    // package:bbb
    {
      LinkedPubPackage linkedPackage = linkedPackages
          .singleWhere((linkedPackage) => linkedPackage.package.name == 'bbb');
      _assertHasLinkedVariable(linkedPackage, 'b1', 'int',
          expectedTypeNameUri: 'dart:core');
      _assertHasLinkedVariable(linkedPackage, 'b2', 'C',
          expectedToBeResolved: false);
    }
  }

  test_getLinkedBundles_missingLibrary() async {
    newFile(
        '$CACHE/aaa/lib/a.dart',
        '''
import 'package:bbb/b2.dart';
int a1;
B2 a2;
''');
    newFile(
        '$CACHE/bbb/lib/b.dart',
        '''
class B {}
int b = 42;
''');

    // Configure packages resolution.
    Folder libFolderA = newFolder('$CACHE/aaa/lib');
    Folder libFolderB = newFolder('$CACHE/bbb/lib');
    context.sourceFactory = new SourceFactory(<UriResolver>[
      sdkResolver,
      resourceResolver,
      new PackageMapUriResolver(resourceProvider, {
        'aaa': [libFolderA],
        'bbb': [libFolderB],
      })
    ]);

    // Ensure unlinked bundles.
    manager.getUnlinkedBundles(context);
    await manager.onUnlinkedComplete;

    // Try to link.
    // Both 'aaa' and 'bbb' are linked.
    // The name 'B2' in 'a.dart' is not resolved.
    List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
    expect(linkedPackages, hasLength(2));

    // package:aaa
    {
      LinkedPubPackage linkedPackage = linkedPackages
          .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa');
      _assertHasLinkedVariable(linkedPackage, 'a1', 'int',
          expectedTypeNameUri: 'dart:core');
      _assertHasLinkedVariable(linkedPackage, 'a2', 'B2',
          expectedToBeResolved: false);
    }

    // package:bbb
    {
      LinkedPubPackage linkedPackage = linkedPackages
          .singleWhere((linkedPackage) => linkedPackage.package.name == 'bbb');
      _assertHasLinkedVariable(linkedPackage, 'b', 'int',
          expectedTypeNameUri: 'dart:core');
    }
  }

  test_getLinkedBundles_missingLibrary_hasCycle() async {
    newFile(
        '$CACHE/aaa/lib/a.dart',
        '''
import 'package:bbb/b.dart';
B a;
''');
    newFile(
        '$CACHE/bbb/lib/b.dart',
        '''
import 'package:aaa/a.dart';
import 'package:ccc/c2.dart';
class B {}
int b1;
C2 b2;
''');
    newFile(
        '$CACHE/ccc/lib/c.dart',
        '''
class C {}
int c;
''');

    // Configure packages resolution.
    Folder libFolderA = newFolder('$CACHE/aaa/lib');
    Folder libFolderB = newFolder('$CACHE/bbb/lib');
    Folder libFolderC = newFolder('$CACHE/ccc/lib');
    context.sourceFactory = new SourceFactory(<UriResolver>[
      sdkResolver,
      resourceResolver,
      new PackageMapUriResolver(resourceProvider, {
        'aaa': [libFolderA],
        'bbb': [libFolderB],
        'ccc': [libFolderC],
      })
    ]);

    // Ensure unlinked bundles.
    manager.getUnlinkedBundles(context);
    await manager.onUnlinkedComplete;

    // Try to link.
    // All bundles 'aaa' and 'bbb' and 'ccc' are linked.
    // The name 'C2' in 'b.dart' is not resolved.
    // We have the corresponding unlinked bundle, and it is full, so if it does
    // not have the library 'package:ccc/c2.dart', this means that this library
    // does not exist in 'ccc' at all.
    List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
    expect(linkedPackages, hasLength(3));

    // package:aaa
    {
      LinkedPubPackage linkedPackage = linkedPackages
          .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa');
      _assertHasLinkedVariable(linkedPackage, 'a', 'B',
          expectedTypeNameUri: 'package:bbb/b.dart');
    }

    // package:bbb
    {
      LinkedPubPackage linkedPackage = linkedPackages
          .singleWhere((linkedPackage) => linkedPackage.package.name == 'bbb');
      _assertHasLinkedVariable(linkedPackage, 'b1', 'int',
          expectedTypeNameUri: 'dart:core');
      _assertHasLinkedVariable(linkedPackage, 'b2', 'C2',
          expectedToBeResolved: false);
    }

    // package:ccc
    {
      LinkedPubPackage linkedPackage = linkedPackages
          .singleWhere((linkedPackage) => linkedPackage.package.name == 'ccc');
      _assertHasLinkedVariable(linkedPackage, 'c', 'int',
          expectedTypeNameUri: 'dart:core');
    }
  }

  test_getLinkedBundles_noCycle() async {
    newFile(
        '$CACHE/aaa/lib/a.dart',
        '''
class A {}
int a;
''');
    newFile(
        '$CACHE/bbb/lib/b.dart',
        '''
import 'package:aaa/a.dart';
A b;
''');

    // Configure packages resolution.
    Folder libFolderA = newFolder('$CACHE/aaa/lib');
    Folder libFolderB = newFolder('$CACHE/bbb/lib');
    context.sourceFactory = new SourceFactory(<UriResolver>[
      sdkResolver,
      resourceResolver,
      new PackageMapUriResolver(resourceProvider, {
        'aaa': [libFolderA],
        'bbb': [libFolderB],
      })
    ]);

    // Ensure unlinked bundles.
    manager.getUnlinkedBundles(context);
    await manager.onUnlinkedComplete;

    // Now we should be able to get linked bundles.
    List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
    expect(linkedPackages, hasLength(2));

    // package:aaa
    {
      LinkedPubPackage linkedPackage = linkedPackages
          .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa');
      _assertHasLinkedVariable(linkedPackage, 'a', 'int',
          expectedTypeNameUri: 'dart:core');
    }

    // package:bbb
    {
      LinkedPubPackage linkedPackage = linkedPackages
          .singleWhere((linkedPackage) => linkedPackage.package.name == 'bbb');
      _assertHasLinkedVariable(linkedPackage, 'b', 'A',
          expectedTypeNameUri: 'package:aaa/a.dart');
    }
  }

  test_getLinkedBundles_noCycle_relativeUri() async {
    newFile(
        '$CACHE/aaa/lib/a.dart',
        '''
import 'src/a2.dart';
A a;
''');
    newFile(
        '$CACHE/aaa/lib/src/a2.dart',
        '''
class A {}
''');

    // Configure packages resolution.
    Folder libFolderA = newFolder('$CACHE/aaa/lib');
    context.sourceFactory = new SourceFactory(<UriResolver>[
      sdkResolver,
      resourceResolver,
      new PackageMapUriResolver(resourceProvider, {
        'aaa': [libFolderA],
      })
    ]);

    // Ensure unlinked bundles.
    manager.getUnlinkedBundles(context);
    await manager.onUnlinkedComplete;

    // Link.
    List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
    expect(linkedPackages, hasLength(1));

    // package:aaa
    {
      LinkedPubPackage linkedPackage = linkedPackages
          .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa');
      _assertHasLinkedVariable(linkedPackage, 'a', 'A',
          expectedTypeNameUri: 'src/a2.dart');
    }
  }

  test_getLinkedBundles_noCycle_withExport() async {
    newFile(
        '$CACHE/aaa/lib/a.dart',
        '''
import 'package:bbb/b.dart';
C a;
''');
    newFile(
        '$CACHE/bbb/lib/b.dart',
        '''
export 'package:ccc/c.dart';
''');
    newFile(
        '$CACHE/ccc/lib/c.dart',
        '''
class C {}
''');

    // Configure packages resolution.
    Folder libFolderA = newFolder('$CACHE/aaa/lib');
    Folder libFolderB = newFolder('$CACHE/bbb/lib');
    Folder libFolderC = newFolder('$CACHE/ccc/lib');
    context.sourceFactory = new SourceFactory(<UriResolver>[
      sdkResolver,
      resourceResolver,
      new PackageMapUriResolver(resourceProvider, {
        'aaa': [libFolderA],
        'bbb': [libFolderB],
        'ccc': [libFolderC],
      })
    ]);

    // Ensure unlinked bundles.
    manager.getUnlinkedBundles(context);
    await manager.onUnlinkedComplete;

    // Now we should be able to get linked bundles.
    List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
    expect(linkedPackages, hasLength(3));

    // package:aaa
    {
      LinkedPubPackage linkedPackage = linkedPackages
          .singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa');
      _assertHasLinkedVariable(linkedPackage, 'a', 'C',
          expectedTypeNameUri: 'package:ccc/c.dart');
    }
  }

  test_getLinkedBundles_wrongScheme() async {
    newFile(
        '$CACHE/aaa/lib/a.dart',
        '''
import 'xxx:yyy/zzz.dart';
int a1;
Z a2;
''');

    // Configure packages resolution.
    Folder libFolderA = newFolder('$CACHE/aaa/lib');
    context.sourceFactory = new SourceFactory(<UriResolver>[
      sdkResolver,
      resourceResolver,
      new PackageMapUriResolver(resourceProvider, {
        'aaa': [libFolderA],
      })
    ]);

    // Ensure unlinked bundles.
    manager.getUnlinkedBundles(context);
    await manager.onUnlinkedComplete;

    // Try to link.
    // The package 'aaa' is not linked.
    // We don't know how to handle the URI scheme 'xxx'.
    List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
    expect(linkedPackages, hasLength(0));
  }

  test_getPackageName() {
    String getPackageName(String uriStr) {
      return PubSummaryManager.getPackageName(uriStr);
    }

    expect(getPackageName('package:foo/bar.dart'), 'foo');
    expect(getPackageName('package:foo/bar/baz.dart'), 'foo');
    expect(getPackageName('wrong:foo/bar.dart'), isNull);
    expect(getPackageName('package:foo'), isNull);
  }

  test_getUnlinkedBundles() async {
    // Create package files.
    newFile(
        '$CACHE/aaa/lib/a.dart',
        '''
class A {}
''');
    newFile(
        '$CACHE/aaa/lib/src/a2.dart',
        '''
class A2 {}
''');
    newFile(
        '$CACHE/bbb/lib/b.dart',
        '''
class B {}
''');

    // Configure packages resolution.
    Folder libFolderA = newFolder('$CACHE/aaa/lib');
    Folder libFolderB = newFolder('$CACHE/bbb/lib');
    context.sourceFactory = new SourceFactory(<UriResolver>[
      sdkResolver,
      resourceResolver,
      new PackageMapUriResolver(resourceProvider, {
        'aaa': [libFolderA],
        'bbb': [libFolderB],
      })
    ]);

    // No unlinked bundles yet.
    {
      Map<PubPackage, PackageBundle> bundles =
          manager.getUnlinkedBundles(context);
      expect(bundles, isEmpty);
    }

    // The requested unlinked bundles must be available after the wait.
    await manager.onUnlinkedComplete;
    {
      Map<PubPackage, PackageBundle> bundles =
          manager.getUnlinkedBundles(context);
      expect(bundles, hasLength(2));
      {
        PackageBundle bundle = _getBundleByPackageName(bundles, 'aaa');
        expect(bundle.linkedLibraryUris, isEmpty);
        expect(bundle.unlinkedUnitUris,
            ['package:aaa/a.dart', 'package:aaa/src/a2.dart']);
        expect(bundle.unlinkedUnits, hasLength(2));
        expect(bundle.unlinkedUnits[0].classes.map((c) => c.name), ['A']);
        expect(bundle.unlinkedUnits[1].classes.map((c) => c.name), ['A2']);
      }
      {
        PackageBundle bundle = _getBundleByPackageName(bundles, 'bbb');
        expect(bundle.linkedLibraryUris, isEmpty);
        expect(bundle.unlinkedUnitUris, ['package:bbb/b.dart']);
        expect(bundle.unlinkedUnits, hasLength(1));
        expect(bundle.unlinkedUnits[0].classes.map((c) => c.name), ['B']);
      }
    }

    // The files must be created.
    _assertFileExists(libFolderA.parent, PubSummaryManager.UNLINKED_NAME);
    _assertFileExists(libFolderA.parent, PubSummaryManager.UNLINKED_SPEC_NAME);
    _assertFileExists(libFolderB.parent, PubSummaryManager.UNLINKED_NAME);
    _assertFileExists(libFolderB.parent, PubSummaryManager.UNLINKED_SPEC_NAME);
  }

  test_getUnlinkedBundles_inconsistent_majorVersion() async {
    // Create package files.
    newFile(
        '$CACHE/aaa/lib/a.dart',
        '''
class A {}
''');

    // Configure packages resolution.
    Folder libFolder = newFolder('$CACHE/aaa/lib');
    context.sourceFactory = new SourceFactory(<UriResolver>[
      sdkResolver,
      resourceResolver,
      new PackageMapUriResolver(resourceProvider, {
        'aaa': [libFolder],
      })
    ]);

    /**
     * Verify that the [manager] has exactly one cache bundle `aaa`.
     */
    void _assertSingleBundle() {
      Map<PubPackage, PackageBundle> bundles =
          manager.getUnlinkedBundles(context);
      expect(bundles, hasLength(1));
      PackageBundle bundle = _getBundleByPackageName(bundles, 'aaa');
      expect(bundle.unlinkedUnitUris, ['package:aaa/a.dart']);
    }

    // Compute the bundle using a non-default major version.
    _createManager(majorVersion: 12345);
    manager.getUnlinkedBundles(context);
    await manager.onUnlinkedComplete;
    _assertSingleBundle();

    // Recompute when using the default major version.
    _createManager();
    expect(manager.getUnlinkedBundles(context), isEmpty);

    // Wait for the bundle to be computed.
    await manager.onUnlinkedComplete;
    _assertSingleBundle();
    _assertFileExists(libFolder.parent, PubSummaryManager.UNLINKED_NAME);
    _assertFileExists(libFolder.parent, PubSummaryManager.UNLINKED_SPEC_NAME);

    // Can read from the file again.
    _createManager();
    _assertSingleBundle();
  }

  test_getUnlinkedBundles_notPubCache_dontCreate() async {
    String aaaPath = '/Users/user/projects/aaa';
    // Create package files.
    newFile(
        '$aaaPath/lib/a.dart',
        '''
class A {}
''');
    newFile(
        '$CACHE/bbb/lib/b.dart',
        '''
class B {}
''');

    // Configure packages resolution.
    Folder libFolderA = getFolder('$aaaPath/lib');
    Folder libFolderB = newFolder('$CACHE/bbb/lib');
    context.sourceFactory = new SourceFactory(<UriResolver>[
      sdkResolver,
      resourceResolver,
      new PackageMapUriResolver(resourceProvider, {
        'aaa': [libFolderA],
        'bbb': [libFolderB],
      })
    ]);

    // No unlinked bundles initially.
    {
      Map<PubPackage, PackageBundle> bundles =
          manager.getUnlinkedBundles(context);
      expect(bundles, isEmpty);
    }

    // Wait for unlinked bundles to be computed.
    await manager.onUnlinkedComplete;
    Map<PubPackage, PackageBundle> bundles =
        manager.getUnlinkedBundles(context);
    // We have just one bundle - for 'bbb'.
    expect(bundles, hasLength(1));
    // We computed the unlinked bundle for 'bbb'.
    {
      PackageBundle bundle = _getBundleByPackageName(bundles, 'bbb');
      expect(bundle.linkedLibraryUris, isEmpty);
      expect(bundle.unlinkedUnitUris, ['package:bbb/b.dart']);
      expect(bundle.unlinkedUnits, hasLength(1));
      expect(bundle.unlinkedUnits[0].classes.map((c) => c.name), ['B']);
    }

    // The files must be created.
    _assertFileExists(libFolderB.parent, PubSummaryManager.UNLINKED_NAME);
    _assertFileExists(libFolderB.parent, PubSummaryManager.UNLINKED_SPEC_NAME);
  }

  test_getUnlinkedBundles_notPubCache_useExisting() async {
    String aaaPath = '/Users/user/projects/aaa';
    // Create package files.
    {
      File file = newFile(
          '$aaaPath/lib/a.dart',
          '''
class A {}
''');
      PackageBundleAssembler assembler = new PackageBundleAssembler()
        ..addUnlinkedUnit(
            file.createSource(Uri.parse('package:aaa/a.dart')),
            new UnlinkedUnitBuilder());
      resourceProvider.newFileWithBytes(
          resourceProvider
              .convertPath('$aaaPath/${PubSummaryManager.UNLINKED_SPEC_NAME}'),
          assembler.assemble().toBuffer());
    }
    newFile(
        '$CACHE/bbb/lib/b.dart',
        '''
class B {}
''');

    // Configure packages resolution.
    Folder libFolderA = getFolder('$aaaPath/lib');
    Folder libFolderB = newFolder('$CACHE/bbb/lib');
    context.sourceFactory = new SourceFactory(<UriResolver>[
      sdkResolver,
      resourceResolver,
      new PackageMapUriResolver(resourceProvider, {
        'aaa': [libFolderA],
        'bbb': [libFolderB],
      })
    ]);

    // Request already available unlinked bundles.
    {
      Map<PubPackage, PackageBundle> bundles =
          manager.getUnlinkedBundles(context);
      expect(bundles, hasLength(1));
      // We get the unlinked bundle for 'aaa' because it already exists.
      {
        PackageBundle bundle = _getBundleByPackageName(bundles, 'aaa');
        expect(bundle, isNotNull);
      }
    }

    // Wait for unlinked bundles to be computed.
    await manager.onUnlinkedComplete;
    Map<PubPackage, PackageBundle> bundles =
        manager.getUnlinkedBundles(context);
    expect(bundles, hasLength(2));
    // We still have the unlinked bundle for 'aaa'.
    {
      PackageBundle bundle = _getBundleByPackageName(bundles, 'aaa');
      expect(bundle, isNotNull);
    }
    // We computed the unlinked bundle for 'bbb'.
    {
      PackageBundle bundle = _getBundleByPackageName(bundles, 'bbb');
      expect(bundle.linkedLibraryUris, isEmpty);
      expect(bundle.unlinkedUnitUris, ['package:bbb/b.dart']);
      expect(bundle.unlinkedUnits, hasLength(1));
      expect(bundle.unlinkedUnits[0].classes.map((c) => c.name), ['B']);
    }

    // The files must be created.
    _assertFileExists(libFolderB.parent, PubSummaryManager.UNLINKED_NAME);
    _assertFileExists(libFolderB.parent, PubSummaryManager.UNLINKED_SPEC_NAME);
  }

  test_getUnlinkedBundles_notPubCache_useExisting_inconsistent() async {
    String aaaPath = '/Users/user/projects/aaa';
    // Create package files.
    newFile(
        '$aaaPath/lib/a.dart',
        '''
class A {}
''');

    // Compute the bundles.
    Folder libFolderA = getFolder('$aaaPath/lib');
    await new PubSummaryManager(resourceProvider, '_.temp')
        .computeUnlinkedForFolder('aaa', libFolderA);

    // Configure packages resolution.
    context.sourceFactory = new SourceFactory(<UriResolver>[
      sdkResolver,
      resourceResolver,
      new PackageMapUriResolver(resourceProvider, {
        'aaa': [libFolderA],
      })
    ]);

    // Request already available unlinked bundles.
    expect(manager.getUnlinkedBundles(context), hasLength(1));

    // Update a Dart file.
    // So, the cached bundle cannot be reused.
    resourceProvider.updateFile(
        resourceProvider.convertPath('$aaaPath/lib/a.dart'),
        '''
class A2 {}
''');
    _createManager();
    expect(manager.getUnlinkedBundles(context), isEmpty);

    // ...and because it is not in the pub cache, it will not be recomputed.
    await manager.onUnlinkedComplete;
    expect(manager.getUnlinkedBundles(context), isEmpty);
  }

  test_getUnlinkedBundles_nullPackageMap() async {
    context.sourceFactory =
        new SourceFactory(<UriResolver>[sdkResolver, resourceResolver]);
    Map<PubPackage, PackageBundle> bundles =
        manager.getUnlinkedBundles(context);
    expect(bundles, isEmpty);
  }

  test_isPathInPubCache_posix() {
    expect(
        PubSummaryManager.isPathInPubCache(pathos.posix,
            '/home/.pub-cache/hosted/pub.dartlang.org/foo/lib/bar.dart'),
        isTrue);
    expect(
        PubSummaryManager.isPathInPubCache(
            pathos.posix, '/home/.pub-cache/foo/lib/bar.dart'),
        isTrue);
    expect(
        PubSummaryManager.isPathInPubCache(
            pathos.posix, '/home/sources/dart/foo/lib/bar.dart'),
        isFalse);
  }

  test_isPathInPubCache_windows() {
    expect(
        PubSummaryManager.isPathInPubCache(pathos.windows,
            r'C:\Users\user\Setters\Pub\Cache\hosted\foo\lib\bar.dart'),
        isTrue);
    expect(
        PubSummaryManager.isPathInPubCache(
            pathos.windows, r'C:\Users\user\Sources\Dart\foo\lib\bar.dart'),
        isFalse);
  }

  void _assertFileExists(Folder folder, String fileName) {
    expect(folder.getChildAssumingFile(fileName).exists, isTrue);
  }

  void _assertHasLinkedVariable(LinkedPubPackage linkedPackage,
      String variableName, String expectedTypeName,
      {bool expectedToBeResolved: true,
      String expectedTypeNameUri: 'shouldBeSpecifiedIfResolved'}) {
    PackageBundle unlinked = linkedPackage.unlinked;
    PackageBundle linked = linkedPackage.linked;
    expect(unlinked, isNotNull);
    expect(linked, isNotNull);
    for (int i = 0; i < unlinked.unlinkedUnitUris.length; i++) {
      String unlinkedUnitUri = unlinked.unlinkedUnitUris[i];
      UnlinkedUnit unlinkedUnit = unlinked.unlinkedUnits[i];
      for (UnlinkedVariable v in unlinkedUnit.variables) {
        if (v.name == variableName) {
          int typeNameReference = v.type.reference;
          expect(unlinkedUnit.references[typeNameReference].name,
              expectedTypeName);
          for (int j = 0; j < linked.linkedLibraryUris.length; j++) {
            String linkedLibraryUri = linked.linkedLibraryUris[j];
            if (linkedLibraryUri == unlinkedUnitUri) {
              LinkedLibrary linkedLibrary = linked.linkedLibraries[j];
              LinkedUnit linkedUnit = linkedLibrary.units.single;
              int typeNameDependency =
                  linkedUnit.references[typeNameReference].dependency;
              if (expectedToBeResolved) {
                expect(linkedLibrary.dependencies[typeNameDependency].uri,
                    expectedTypeNameUri);
              } else {
                expect(typeNameDependency, isZero);
              }
              return;
            }
          }
          fail('Cannot find linked unit for $variableName in $linkedPackage');
        }
      }
    }
    fail('Cannot find variable $variableName in $linkedPackage');
  }

  void _createManager(
      {bool allowLinking: true,
      int majorVersion: PackageBundleAssembler.currentMajorVersion}) {
    manager = new PubSummaryManager(resourceProvider, '_.temp',
        allowLinking: allowLinking, majorVersion: majorVersion);
  }

  LinkedPubPackage _getLinkedPackage(
      List<LinkedPubPackage> packages, String name) {
    return packages
        .singleWhere((linkedPackage) => linkedPackage.package.name == name);
  }

  _testImpl_getLinkedBundles_cached_declaredVariables(
      String importOrExport) async {
    String pathA = '$CACHE/aaa/lib';
    newFile('$pathA/foo.dart', 'class A {}');
    newFile('$pathA/foo_io.dart', 'class A {}');
    newFile('$pathA/foo_html.dart', 'class A {}');
    newFile(
        '$pathA/user.dart',
        '''
$importOrExport 'foo.dart'
  if (dart.library.io) 'foo_io.dart'
  if (dart.library.html) 'foo_html.dart';
''');
    // Configure packages resolution.
    Folder libFolderA = newFolder(pathA);
    context.sourceFactory = new SourceFactory(<UriResolver>[
      sdkResolver,
      resourceResolver,
      new PackageMapUriResolver(resourceProvider, {
        'aaa': [libFolderA],
      })
    ]);

    void _assertDependencyInUser(PackageBundle bundle, String shortName) {
      for (var i = 0; i < bundle.linkedLibraryUris.length; i++) {
        if (bundle.linkedLibraryUris[i].endsWith('user.dart')) {
          LinkedLibrary library = bundle.linkedLibraries[i];
          expect(library.dependencies.map((d) => d.uri),
              unorderedEquals(['', 'dart:core', shortName]));
          return;
        }
      }
      fail('Not found user.dart in $bundle');
    }

    // Session 1.
    // Create the linked bundle and cache it in a file.
    {
      // Ensure unlinked bundles.
      manager.getUnlinkedBundles(context);
      await manager.onUnlinkedComplete;

      // Now we should be able to get the linked bundle.
      List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
      expect(linkedPackages, hasLength(1));
    }

    // Session 2.
    // Recreate manager and don't allow it to perform new linking.
    // Set a declared variable, which is not used in the package.
    // We still can get the cached linked bundle.
    {
      context.declaredVariables.define('not.used.variable', 'baz');
      _createManager(allowLinking: false);
      List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
      expect(linkedPackages, hasLength(1));
      _assertDependencyInUser(linkedPackages.single.linked, 'foo.dart');
    }

    // Session 3.
    // Recreate manager and don't allow it to perform new linking.
    // Set the value of a referenced declared variable.
    // So, we cannot use the previously cached linked bundle.
    {
      context.declaredVariables.define('dart.library.io', 'does-not-matter');
      _createManager(allowLinking: false);
      List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
      expect(linkedPackages, isEmpty);
    }

    // Session 4.
    // Enable new linking, and configure to use 'foo_html.dart'.
    {
      context.declaredVariables.define('dart.library.html', 'true');
      _createManager();
      List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
      expect(linkedPackages, hasLength(1));
      _assertDependencyInUser(linkedPackages.single.linked, 'foo_html.dart');
    }
  }

  static PackageBundle _getBundleByPackageName(
      Map<PubPackage, PackageBundle> bundles, String name) {
    PubPackage package =
        bundles.keys.singleWhere((package) => package.name == name);
    return bundles[package];
  }
}
