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

@TestOn('vm')
library;

import 'package:pub/src/exit_codes.dart' as exit_codes;
import 'package:pub/src/io.dart';
import 'package:pub/src/path.dart';
import 'package:pub/src/sdk/sdk_package_config.dart';
import 'package:test/test.dart';

import 'descriptor.dart' as d;
import 'test_pub.dart';

void main() {
  forBothPubGetAndUpgrade((command) {
    group('flutter', () {
      setUp(() async {
        final server = await servePackages();
        server.serve('bar', '1.0.0');

        await d.dir('flutter', [
          d.dir('packages', [
            d.dir('foo', [
              d.libDir('foo', 'foo 0.0.1'),
              d.libPubspec('foo', '0.0.1', deps: {'bar': 'any'}),
            ]),
          ]),
          d.dir('bin/cache/pkg', [
            d.dir('baz', [
              d.libDir('baz', 'foo 0.0.1'),
              d.libPubspec('baz', '0.0.1'),
            ]),
          ]),
          d.flutterVersion('1.2.3'),
        ]).create();
      });

      test("gets an SDK dependency's dependencies", () async {
        await d
            .appDir(
              dependencies: {
                'foo': {'sdk': 'flutter'},
              },
            )
            .create();
        await pubCommand(
          command,
          environment: {'FLUTTER_ROOT': p.join(d.sandbox, 'flutter')},
        );
        await d
            .appPackageConfigFile(
              [
                d.packageConfigEntry(
                  name: 'foo',
                  path: p.join(d.sandbox, 'flutter', 'packages', 'foo'),
                ),
                d.packageConfigEntry(name: 'bar', version: '1.0.0'),
              ],
              flutterRoot: p.join(d.sandbox, 'flutter'),
              flutterVersion: '1.2.3',
            )
            .validate();
      });

      test('gets an SDK dependency from bin/cache/pkg', () async {
        await d
            .appDir(
              dependencies: {
                'baz': {'sdk': 'flutter'},
              },
            )
            .create();
        await pubCommand(
          command,
          environment: {'FLUTTER_ROOT': p.join(d.sandbox, 'flutter')},
        );

        await d
            .appPackageConfigFile(
              [
                d.packageConfigEntry(
                  name: 'baz',
                  path: p.join(
                    d.sandbox,
                    'flutter',
                    'bin',
                    'cache',
                    'pkg',
                    'baz',
                  ),
                ),
              ],
              flutterRoot: p.join(d.sandbox, 'flutter'),
              flutterVersion: '1.2.3',
            )
            .validate();
      });

      test('unlocks an SDK dependency when the version changes', () async {
        await d
            .appDir(
              dependencies: {
                'foo': {'sdk': 'flutter'},
              },
            )
            .create();
        await pubCommand(
          command,
          environment: {'FLUTTER_ROOT': p.join(d.sandbox, 'flutter')},
        );

        await d
            .file(
              '$appPath/pubspec.lock',
              allOf([contains('0.0.1'), isNot(contains('0.0.2'))]),
            )
            .validate();

        await d.dir('flutter/packages/foo', [
          d.libPubspec('foo', '0.0.2'),
        ]).create();
        await pubCommand(
          command,
          environment: {'FLUTTER_ROOT': p.join(d.sandbox, 'flutter')},
        );

        await d
            .file(
              '$appPath/pubspec.lock',
              allOf([isNot(contains('0.0.1')), contains('0.0.2')]),
            )
            .validate();
      });

      // Regression test for #1883
      test("doesn't fail if the Flutter SDK's version file doesn't exist when "
          'nothing depends on Flutter', () async {
        await d.appDir().create();
        deleteEntry(
          p.join(d.sandbox, 'flutter', 'bin', 'cache', 'flutterVersion'),
        );
        await pubCommand(
          command,
          environment: {'FLUTTER_ROOT': p.join(d.sandbox, 'flutter')},
        );
        await d
            .appPackageConfigFile(
              [],
              flutterRoot: p.join(d.sandbox, 'flutter'),
              flutterVersion: '1.2.3',
            )
            .validate();
      });

      group('fails if', () {
        test("the version constraint doesn't match", () async {
          await d
              .appDir(
                dependencies: {
                  'foo': {'sdk': 'flutter', 'version': '^1.0.0'},
                },
              )
              .create();
          await pubCommand(
            command,
            environment: {'FLUTTER_ROOT': p.join(d.sandbox, 'flutter')},
            error: contains(
              '''
Because myapp depends on foo ^1.0.0 from sdk which doesn't match any versions, version solving failed.''',
            ),
          );
        });

        test('the SDK is unknown', () async {
          await d
              .appDir(
                dependencies: {
                  'foo': {'sdk': 'unknown'},
                },
              )
              .create();
          await pubCommand(
            command,
            error: equalsIgnoringWhitespace(
              '''
Because myapp depends on foo from sdk which doesn't exist (unknown SDK "unknown"), version solving failed.''',
            ),
            exitCode: exit_codes.UNAVAILABLE,
          );
        });

        test('the SDK is unavailable', () async {
          await d
              .appDir(
                dependencies: {
                  'foo': {'sdk': 'flutter'},
                },
              )
              .create();
          await pubCommand(
            command,
            error: equalsIgnoringWhitespace("""
              Because myapp depends on foo from sdk which doesn't exist (the
                Flutter SDK is not available), version solving failed.

              Flutter users should use `flutter pub` instead of `dart pub`.
            """),
            exitCode: exit_codes.UNAVAILABLE,
          );
        });

        test("the SDK doesn't contain the package", () async {
          await d
              .appDir(
                dependencies: {
                  'bar': {'sdk': 'flutter'},
                },
              )
              .create();
          await pubCommand(
            command,
            environment: {'FLUTTER_ROOT': p.join(d.sandbox, 'flutter')},
            error: equalsIgnoringWhitespace("""
              Because myapp depends on bar from sdk which doesn't exist
                (could not find package bar in the Flutter SDK), version solving
                failed.
            """),
            exitCode: exit_codes.UNAVAILABLE,
          );
        });

        test("the Dart SDK doesn't contain the package", () async {
          await d
              .appDir(
                dependencies: {
                  'bar': {'sdk': 'dart'},
                },
              )
              .create();
          await pubCommand(
            command,
            error: equalsIgnoringWhitespace("""
              Because myapp depends on bar from sdk which doesn't exist
                (could not find package bar in the Dart SDK), version solving
                failed.
            """),
            exitCode: exit_codes.UNAVAILABLE,
          );
        });
      });

      test('supports the Fuchsia SDK', () async {
        renameDir(p.join(d.sandbox, 'flutter'), p.join(d.sandbox, 'fuchsia'));

        await d
            .appDir(
              dependencies: {
                'foo': {'sdk': 'fuchsia'},
              },
            )
            .create();
        await pubCommand(
          command,
          environment: {'FUCHSIA_DART_SDK_ROOT': p.join(d.sandbox, 'fuchsia')},
        );
        await d.appPackageConfigFile([
          d.packageConfigEntry(
            name: 'foo',
            path: p.join(d.sandbox, 'fuchsia', 'packages', 'foo'),
          ),
          d.packageConfigEntry(name: 'bar', version: '1.0.0'),
        ]).validate();
      });
    });

    group('dart', () {
      group('with valid SDK configuration', () {
        setUp(() async {
          final server = await servePackages();
          server.serve('bar', '1.0.0');

          await d.dir('dart', [
            d.dir('packages', [
              d.dir('foo', [
                d.libDir('foo', 'foo 0.0.1'),
                d.libPubspec('foo', '0.0.1', deps: {}),
              ]),
            ]),
            d.sdkPackagesConfig(
              SdkPackageConfig('dart', {
                'foo': SdkPackage('foo', 'packages/foo'),
              }, 1),
            ),
          ]).create();
        });

        test('gets an SDK dependency from sdk_packages.yaml', () async {
          await d
              .appDir(
                dependencies: {
                  'foo': {'sdk': 'dart', 'version': '^0.0.1'},
                },
              )
              .create();

          await pubCommand(
            command,
            environment: {'DART_ROOT': p.join(d.sandbox, 'dart')},
          );

          await d.appPackageConfigFile([
            d.packageConfigEntry(
              name: 'foo',
              path: p.join(d.sandbox, 'dart', 'packages', 'foo'),
              version: '0.0.1',
            ),
          ]).validate();
        });

        test('fails if the version range isn\'t compatible with the SDK '
            'dependency from sdk_packages.yaml', () async {
          await d
              .appDir(
                dependencies: {
                  'foo': {'sdk': 'dart', 'version': '^1.0.0'},
                },
              )
              .create();

          await pubCommand(
            command,
            environment: {'DART_ROOT': p.join(d.sandbox, 'dart')},
            error: equalsIgnoringWhitespace('''
             Because myapp depends on foo ^1.0.0 from sdk which doesn't match
             any versions, version solving failed.

             You can try the following suggestion to make the pubspec resolve:

             * Try updating the following constraints: dart pub add
               foo:'{"version":"^0.0.1","sdk":"dart"}'
            '''),
          );
        });
      });

      test('does not allow non-SDK deps in SDK packages', () async {
        final server = await servePackages();
        server.serve('bar', '1.0.0');

        await d.dir('dart', [
          d.dir('packages', [
            d.dir('foo', [
              d.libDir('foo', 'foo 0.0.1'),
              d.libPubspec('foo', '0.0.1', deps: {'bar': '^1.0.0'}),
            ]),
          ]),
          d.sdkPackagesConfig(
            SdkPackageConfig('dart', {
              'foo': SdkPackage('foo', 'packages/foo'),
            }, 1),
          ),
        ]).create();

        await d
            .appDir(
              dependencies: {
                'foo': {'sdk': 'dart', 'version': '^1.0.0'},
              },
            )
            .create();

        await pubCommand(
          command,
          environment: {'DART_ROOT': p.join(d.sandbox, 'dart')},
          error: contains(
            'Unsupported operation: Only SDK packages are allowed as regular '
            'dependencies for packages vendored '
            'by the dart SDK, but the `foo` '
            'package has a hosted dependency on `bar`.',
          ),
        );
      });

      test('expects a value of `dart` for the `sdk` field', () async {
        final server = await servePackages();
        server.serve('bar', '1.0.0');

        await d.dir('dart', [
          d.dir('packages', [
            d.dir('foo', [
              d.libDir('foo', 'foo 0.0.1'),
              d.libPubspec('foo', '0.0.1', deps: {}),
            ]),
          ]),
          d.sdkPackagesConfig(
            SdkPackageConfig('fuschia', {
              'foo': SdkPackage('foo', 'packages/foo'),
            }, 1),
          ),
        ]).create();

        await d
            .appDir(
              dependencies: {
                'foo': {'sdk': 'dart', 'version': '^1.0.0'},
              },
            )
            .create();

        await pubCommand(
          command,
          environment: {'DART_ROOT': p.join(d.sandbox, 'dart')},
          error: contains(
            'Expected a configuration for the `dart` sdk but got one for '
            '`fuschia`. (at character 8)',
          ),
          exitCode: 65,
        );
      });
    });
  });
}
