// Copyright (c) 2019, 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/src/context/packages.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:meta/meta.dart';
import 'package:pub_semver/pub_semver.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

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

@reflectiveTest
class PackagesTest with ResourceProviderMixin {
  void setUp() {
    newFile('/test/lib/test.dart', content: '');
  }

  void test_findPackagesFrom_fallbackToDotPackages() {
    newFile('/test/.packages', content: '''
test:lib/
bbb:${toUriStr('/packages/bbb/lib')}
''');

    var packages = findPackagesFrom(
      resourceProvider,
      getFile('/test/lib/a.dart'),
    );

    _assertPackage(
      packages,
      name: 'test',
      expectedLibPath: '/test/lib',
      expectedVersion: null,
    );

    _assertPackage(
      packages,
      name: 'bbb',
      expectedLibPath: '/packages/bbb/lib',
      expectedVersion: null,
    );
  }

  void test_findPackagesFrom_missing() {
    var packages = findPackagesFrom(
      resourceProvider,
      getFile('/test/lib/a.dart'),
    );

    expect(packages.packages, isEmpty);
  }

  void test_findPackagesFrom_preferPackageConfig() {
    newFile('/test/.dart_tool/package_config.json', content: '''
{
  "configVersion": 2,
  "packages": [
    {
      "name": "test",
      "rootUri": "../",
      "packageUri": "lib/",
      "languageVersion": "2.6"
    },
    {
      "name": "aaa",
      "rootUri": "${toUriStr('/packages/aaa')}",
      "packageUri": "lib/",
      "languageVersion": "2.3"
    }
  ]
}
''');

    newFile('/test/.packages', content: '''
test:lib/
bbb:${toUriStr('/packages/bbb/lib')}
''');

    var packages = findPackagesFrom(
      resourceProvider,
      getFile('/test/lib/a.dart'),
    );

    _assertPackage(
      packages,
      name: 'test',
      expectedLibPath: '/test/lib',
      expectedVersion: Version(2, 6, 0),
    );

    _assertPackage(
      packages,
      name: 'aaa',
      expectedLibPath: '/packages/aaa/lib',
      expectedVersion: Version(2, 3, 0),
    );
  }

  test_packageForPath() {
    var packages = Packages(
      {
        'aaa': Package(
          name: 'aaa',
          rootFolder: getFolder('/home/aaa'),
          libFolder: getFolder('/home/aaa/lib'),
          languageVersion: Version.parse('2.7.0'),
        ),
        'bbb': Package(
          name: 'bbb',
          rootFolder: getFolder('/home/aaa/bbb'),
          libFolder: getFolder('/home/aaa/bbb/lib'),
          languageVersion: Version.parse('2.7.0'),
        ),
        'ccc': Package(
          name: 'ccc',
          rootFolder: getFolder('/home/ccc'),
          libFolder: getFolder('/home/ccc/lib'),
          languageVersion: Version.parse('2.7.0'),
        ),
      },
    );

    void check(String posixPath, String expectedPackageName) {
      var path = convertPath(posixPath);
      var package = packages.packageForPath(path);
      expect(package?.name, expectedPackageName);
    }

    check('/home/aaa/lib/a.dart', 'aaa');
    check('/home/aaa/bbb/lib/b.dart', 'bbb');
    check('/home/ccc/lib/c.dart', 'ccc');
    check('/home/ddd/lib/c.dart', null);
  }

  test_parseDotPackagesFile() {
    var file = newFile('/test/.packages', content: '''
# Generated by pub
aaa:${toUriStr('/packages/aaa/lib/')}
test:lib/
''');
    var packages = parseDotPackagesFile(resourceProvider, file);

    _assertPackage(
      packages,
      name: 'test',
      expectedLibPath: '/test/lib',
      expectedVersion: null,
    );

    _assertPackage(
      packages,
      name: 'aaa',
      expectedLibPath: '/packages/aaa/lib',
      expectedVersion: null,
    );
  }

  test_parsePackageConfigJsonFile() {
    var file = newFile('/test/.dart_tool/package_config.json', content: '''
{
  "configVersion": 2,
  "packages": [
    {
      "name": "test",
      "rootUri": "../",
      "packageUri": "lib/",
      "languageVersion": "2.6"
    },
    {
      "name": "aaa",
      "rootUri": "${toUriStr('/packages/aaa')}",
      "packageUri": "lib/",
      "languageVersion": "2.3"
    },
    {
      "name": "bbb",
      "rootUri": "${toUriStr('/packages/bbb')}",
      "packageUri": "lib/"
    }
  ]
}
''');
    var packages = parsePackageConfigJsonFile(resourceProvider, file);

    _assertPackage(
      packages,
      name: 'test',
      expectedLibPath: '/test/lib',
      expectedVersion: Version(2, 6, 0),
    );

    _assertPackage(
      packages,
      name: 'aaa',
      expectedLibPath: '/packages/aaa/lib',
      expectedVersion: Version(2, 3, 0),
    );

    _assertPackage(
      packages,
      name: 'bbb',
      expectedLibPath: '/packages/bbb/lib',
      expectedVersion: null,
    );
  }

  /// New features were added in `2.2.2` over `2.2.0`.
  /// But `2.2.2` is not representable, so we special case it.
  test_parsePackageConfigJsonFile_version222() {
    var file = newFile('/test/.dart_tool/package_config.json', content: '''
{
  "configVersion": 2,
  "packages": [
    {
      "name": "test",
      "rootUri": "../",
      "packageUri": "lib/",
      "languageVersion": "2.2"
    }
  ]
}
''');
    var packages = parsePackageConfigJsonFile(resourceProvider, file);

    _assertPackage(
      packages,
      name: 'test',
      expectedLibPath: '/test/lib',
      expectedVersion: Version(2, 2, 2),
    );
  }

  test_parsePackagesFile_dotPackages() {
    var path = convertPath('/test/.packages');
    newFile(path, content: '''
bbb:${toUriStr('/packages/bbb/lib')}
''');

    var packages = parsePackagesFile(resourceProvider, getFile(path));

    _assertPackage(
      packages,
      name: 'bbb',
      expectedLibPath: '/packages/bbb/lib',
      expectedVersion: null,
    );
  }

  test_parsePackagesFile_packageConfig() {
    var path = convertPath('/test/.dart_tool/package_config.json');
    newFile(path, content: '''
{
  "configVersion": 2,
  "packages": [
    {
      "name": "aaa",
      "rootUri": "${toUriStr('/packages/aaa')}",
      "packageUri": "lib/",
      "languageVersion": "2.3"
    }
  ]
}
''');

    var packages = parsePackagesFile(resourceProvider, getFile(path));

    _assertPackage(
      packages,
      name: 'aaa',
      expectedLibPath: '/packages/aaa/lib',
      expectedVersion: Version(2, 3, 0),
    );
  }

  test_parsePackagesFile_packageConfig_fromDotPackages() {
    newFile('/test/.dart_tool/package_config.json', content: '''
{
  "configVersion": 2,
  "packages": [
    {
      "name": "aaa",
      "rootUri": "${toUriStr('/packages/aaa')}",
      "packageUri": "lib/",
      "languageVersion": "2.3"
    }
  ]
}
''');

    var dotPackagesPath = '/test/.packages';
    newFile(dotPackagesPath, content: '''
bbb:${toUriStr('/packages/bbb/lib')}
''');

    var packages = parsePackagesFile(
      resourceProvider,
      getFile(dotPackagesPath),
    );

    _assertPackage(
      packages,
      name: 'aaa',
      expectedLibPath: '/packages/aaa/lib',
      expectedVersion: Version(2, 3, 0),
    );
  }

  void _assertPackage(
    Packages packages, {
    @required String name,
    @required String expectedLibPath,
    @required Version expectedVersion,
  }) {
    var package = packages[name];
    expect(package.name, name);
    expect(package.libFolder.path, convertPath(expectedLibPath));
    expect(package.languageVersion, expectedVersion);
  }
}
