// Copyright (c) 2013, 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 'dart:async';
import 'dart:convert';

import 'package:path/path.dart' as p;

import 'package:pub/src/exit_codes.dart';
import 'package:test/test.dart';

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

d.DirectoryDescriptor package({
  String version = '1.0.0',
  Map<String, Object?>? deps,
  String? sdk,
}) {
  return d.dir(appPath, [
    d.libPubspec(
      'test_pkg',
      version,
      sdk: sdk ?? defaultSdkConstraint,
      deps: deps,
    ),
    d.file('LICENSE', 'Eh, do what you want.'),
    d.file('README.md', "This package isn't real."),
    d.file('CHANGELOG.md', '# $version\nFirst version\n'),
    d.dir('lib', [d.file('test_pkg.dart', 'int i = 1;')]),
  ]);
}

Future<void> expectValidation({
  Object? message,
  int exitCode = 0,
  Map<String, String> environment = const {},
}) async {
  await runPub(
    output: message ?? contains('Package has 0 warnings.'),
    args: ['publish', '--dry-run'],
    // workingDirectory: d.path(appPath),
    exitCode: exitCode,
    environment: environment,
  );
}

Future<void> expectValidationWarning(
  Object? message, {
  int count = 1,
  Map<String, String> environment = const {},
}) async {
  if (message is String) message = contains(message);
  await expectValidation(
    message: allOf([message, contains('Package has $count warning')]),
    exitCode: DATA,
    environment: environment,
  );
}

Future<void> expectValidationError(
  String message, {
  Map<String, String> environment = const {},
}) async {
  await expectValidation(
    message: allOf([
      contains(message),
      contains('Package validation found the following error:'),
    ]),
    exitCode: DATA,
    environment: environment,
  );
}

Future<void> setUpDependency(
  Map<String, String> dep, {
  String? sdk,
  List<String> hostedVersions = const [],
}) async {
  final server = await servePackages();
  for (final version in hostedVersions) {
    server.serve('foo', version);
  }

  await package(deps: {'foo': dep}, sdk: sdk).create();
}

void main() {
  group('should consider a package valid if it', () {
    test('looks normal', () async {
      await package().create();
      await expectValidation();
    });

    test('with a dependency on a pre-release while being one', () async {
      (await servePackages()).serve('foo', '1.2.3-dev');
      await package(version: '1.0.0-dev', deps: {'foo': '^1.2.3-dev'}).create();
      await expectValidation();
    });

    test(
      'has a git path dependency with an appropriate SDK constraint',
      () async {
        await servePackages();
        await d.git('foo', [
          d.dir('subdir', [d.libPubspec('foo', '1.0.0')]),
        ]).create();
        await package(
          deps: {
            'foo': {
              'git': {'url': '../foo', 'path': 'subdir'},
            },
          },
        ).create();

        // We should get a warning for using a git dependency, but not an error.
        await expectValidationWarning(
          allOf([
            contains('  foo: any'),
            contains("Publishable packages can't have 'git' dependencies"),
          ]),
          count: 2,
        );
      },
    );

    test('depends on Flutter from an SDK source', () async {
      await d.dir('flutter', [d.flutterVersion('1.2.3')]).create();
      await flutterPackage('flutter').create();
      await package(
        deps: {
          'flutter': {'sdk': 'flutter'},
        },
      ).create();

      await expectValidation(
        environment: {'FLUTTER_ROOT': p.join(d.sandbox, 'flutter')},
      );
    });

    test('depends on a package from Flutter '
        'with an appropriate Dart SDK constraint', () async {
      await d.dir('flutter', [d.flutterVersion('1.2.3')]).create();
      await flutterPackage('foo').create();
      await package(
        deps: {
          'foo': {'sdk': 'flutter', 'version': '>=1.2.3 <2.0.0'},
        },
      ).create();

      await expectValidation(
        environment: {'FLUTTER_ROOT': p.join(d.sandbox, 'flutter')},
      );
    });

    test('depends on a package from Fuchsia '
        'with an appropriate Dart SDK constraint', () async {
      await fuchsiaPackage('foo', sdk: '^3.0.0').create();
      await package(
        deps: {
          'foo': {'sdk': 'fuchsia', 'version': '>=1.2.3 <2.0.0'},
        },
      ).create();

      await expectValidation(
        environment: {'FUCHSIA_DART_SDK_ROOT': p.join(d.sandbox, 'fuchsia')},
      );
    });
  });

  group('should consider a package invalid if it', () {
    setUp(package().create);

    group('has a path dependency', () {
      group('where a hosted version exists', () {
        test('and should suggest the hosted primary version', () async {
          await d.dir('foo', [d.libPubspec('foo', '1.2.3')]).create();
          await setUpDependency(
            {'path': p.join(d.sandbox, 'foo')},
            hostedVersions: ['3.0.0-pre', '2.0.0', '1.0.0'],
          );
          await expectValidationError('  foo: ^2.0.0');
        });

        test('and should suggest the hosted prerelease version '
            "if it's the only version available", () async {
          await d.dir('foo', [d.libPubspec('foo', '1.2.3')]).create();
          await setUpDependency(
            {'path': p.join(d.sandbox, 'foo')},
            hostedVersions: ['3.0.0-pre', '2.0.0-pre'],
          );
          await expectValidationError('  foo: ^3.0.0-pre');
        });

        test(
          'and should suggest a tighter constraint if primary is pre-1.0.0',
          () async {
            await d.dir('foo', [d.libPubspec('foo', '1.2.3')]).create();
            await setUpDependency(
              {'path': p.join(d.sandbox, 'foo')},
              hostedVersions: ['0.0.1', '0.0.2'],
            );
            await expectValidationError('  foo: ^0.0.2');
          },
        );
      });

      group('where no hosted version exists', () {
        test("and should use the other source's version", () async {
          await d.dir('foo', [d.libPubspec('foo', '1.2.3')]).create();
          await setUpDependency({
            'path': p.join(d.sandbox, 'foo'),
            'version': '>=1.0.0 <2.0.0',
          });
          await expectValidationError('  foo: ">=1.0.0 <2.0.0"');
        });

        test("and should use the other source's unquoted version if "
            'concrete', () async {
          await d.dir('foo', [d.libPubspec('foo', '0.2.3')]).create();
          await setUpDependency({
            'path': p.join(d.sandbox, 'foo'),
            'version': '0.2.3',
          });
          await expectValidationError('  foo: 0.2.3');
        });
      });
    });

    group('has an unconstrained dependency', () {
      group('with a lockfile', () {
        test(
          'and it should suggest a constraint based on the locked version',
          () async {
            (await servePackages()).serve('foo', '1.2.3');
            await d.dir(appPath, [
              d.libPubspec('test_pkg', '1.0.0', deps: {'foo': 'any'}),
            ]).create();

            await expectValidationWarning('  foo: ^1.2.3');
          },
        );

        test('and it should suggest a concrete constraint '
            'if the locked version is pre-1.0.0', () async {
          (await servePackages()).serve('foo', '0.1.2');

          await d.dir(appPath, [
            d.libPubspec('test_pkg', '1.0.0', deps: {'foo': 'any'}),
            d.file(
              'pubspec.lock',
              jsonEncode({
                'packages': {
                  'foo': {
                    'version': '0.1.2',
                    'source': 'hosted',
                    'description': {'name': 'foo', 'url': 'https://pub.dev'},
                  },
                },
              }),
            ),
          ]).create();

          await expectValidationWarning('  foo: ^0.1.2');
        });
      });
    });

    test('with a dependency on a pre-release without being one', () async {
      (await servePackages()).serve('foo', '1.2.3-dev');

      await d.dir(appPath, [
        d.libPubspec('test_pkg', '1.0.0', deps: {'foo': '^1.2.3-dev'}),
      ]).create();

      await expectValidationWarning('Packages dependent on a pre-release');
    });
    test('with a single-version dependency and it should suggest a '
        'constraint based on the version', () async {
      (await servePackages()).serve('foo', '1.2.3');
      await d.dir(appPath, [
        d.libPubspec('test_pkg', '1.0.0', deps: {'foo': '1.2.3'}),
      ]).create();

      await expectValidationWarning('  foo: ^1.2.3');
    });

    group('has a dependency without a lower bound', () {
      test('and it should suggest a constraint based on the locked '
          'version', () async {
        (await servePackages()).serve('foo', '1.2.3');

        await d.dir(appPath, [
          d.libPubspec('test_pkg', '1.0.0', deps: {'foo': '<3.0.0'}),
          d.file('pubspec.lock'),
        ]).create();

        await expectValidationWarning('  foo: ">=1.2.3 <3.0.0"');
      });

      test('and it should preserve the upper-bound operator', () async {
        (await servePackages()).serve('foo', '1.2.3');
        await d.dir(appPath, [
          d.libPubspec('test_pkg', '1.0.0', deps: {'foo': '<=3.0.0'}),
          d.file(
            'pubspec.lock',
            jsonEncode({
              'packages': {
                'foo': {
                  'version': '1.2.3',
                  'source': 'hosted',
                  'description': {'name': 'foo', 'url': 'https://pub.dev'},
                },
              },
            }),
          ),
        ]).create();

        await expectValidationWarning('  foo: ">=1.2.3 <=3.0.0"');
      });

      test('and it should expand the suggested constraint if the '
          'locked version matches the upper bound', () async {
        (await servePackages()).serve('foo', '1.2.3');

        await d.dir(appPath, [
          d.libPubspec('test_pkg', '1.0.0', deps: {'foo': '<=1.2.3'}),
          d.file(
            'pubspec.lock',
            jsonEncode({
              'packages': {
                'foo': {
                  'version': '1.2.3',
                  'source': 'hosted',
                  'description': {'name': 'foo', 'url': 'https://pub.dev'},
                },
              },
            }),
          ),
        ]).create();

        await expectValidationWarning('  foo: ^1.2.3');
      });
    });

    group('with a dependency without an upper bound', () {
      test(
        'and it should suggest a constraint based on the lower bound',
        () async {
          (await servePackages()).serve('foo', '1.2.3');
          await d.dir(appPath, [
            d.libPubspec('test_pkg', '1.0.0', deps: {'foo': '>=1.2.3'}),
          ]).create();

          await expectValidationWarning('  foo: ^1.2.3');
        },
      );

      test('and it should preserve the lower-bound operator', () async {
        (await servePackages()).serve('foo', '1.2.4');
        await d.dir(appPath, [
          d.libPubspec('test_pkg', '1.0.0', deps: {'foo': '>1.2.3'}),
        ]).create();

        await expectValidationWarning('  foo: ">1.2.3 <2.0.0"');
      });
    });
  });
}

d.Descriptor fuchsiaPackage(
  String name, {
  Map<String, String> deps = const {},
  String? sdk,
}) {
  return d.dir('fuchsia', [
    d.dir('packages', [
      d.dir(name, [
        d.libDir(name, 'f(x) => 2 * x;'),
        d.libPubspec(name, '1.5.0', deps: deps, sdk: sdk),
      ]),
    ]),
  ]);
}

d.Descriptor flutterPackage(
  String name, {
  Map<String, String> deps = const {},
}) {
  return d.dir('flutter', [
    d.dir('packages', [
      d.dir(name, [
        d.libDir(name, 'f(x) => 2 * x;'),
        d.libPubspec(name, '1.5.0', deps: deps),
      ]),
    ]),
  ]);
}
