// Copyright (c) 2020, 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:pub/src/exit_codes.dart';
import 'package:test/test.dart';

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

void main() {
  test('The bound of ">=2.11.0 <3.0.0" is not modified', () async {
    await d.dir(appPath, [
      d.pubspec({
        'name': 'myapp',
        'environment': {'sdk': '>=2.11.0 <3.0.0'},
      }),
    ]).create();

    await pubGet(
      error: contains(
        'The current Dart SDK (3.5.0) only supports null safety.',
      ),
      environment: {'_PUB_TEST_SDK_VERSION': '3.5.0'},
      exitCode: DATA,
    );
  });
  test('The bound of ">=2.12.0 <3.1.0" is not modified', () async {
    await d.dir(appPath, [
      d.pubspec({
        'name': 'myapp',
        'environment': {'sdk': '>=2.12.0 <3.1.0'},
      }),
    ]).create();

    await pubGet(
      error: contains(
        'Because myapp requires SDK version >=2.12.0 <3.1.0, '
        'version solving failed',
      ),
      environment: {'_PUB_TEST_SDK_VERSION': '3.5.0'},
    );
  });

  test('The bound of ">=2.11.0 <2.999.0" is not modified', () async {
    await d.dir(appPath, [
      d.pubspec({
        'name': 'myapp',
        'environment': {'sdk': '>=2.11.0 <2.999.0'},
      }),
    ]).create();

    await pubGet(
      error: contains(
        'The current Dart SDK (3.5.0) only supports null safety.',
      ),
      environment: {'_PUB_TEST_SDK_VERSION': '3.5.0'},
      exitCode: DATA,
    );
  });

  test('The bound of ">=2.11.0 <3.0.0-0.0" is not modified', () async {
    await d.dir(appPath, [
      d.pubspec({
        'name': 'myapp',
        'environment': {'sdk': '>=2.11.0 <3.0.0-0.0'},
      }),
    ]).create();

    await pubGet(
      error: contains(
        'The current Dart SDK (3.5.0) only supports null safety.',
      ),
      environment: {'_PUB_TEST_SDK_VERSION': '3.5.0'},
      exitCode: DATA,
    );
  });

  test('The bound of ">=2.12.0 <3.0.0" is modified', () async {
    await d.dir(appPath, [
      d.pubspec({
        'name': 'myapp',
        'environment': {'sdk': '>=2.12.0 <3.0.0'},
      }),
    ]).create();

    await pubGet(environment: {'_PUB_TEST_SDK_VERSION': '3.5.0'});
  });

  test('The bound of ">=2.12.0 <3.0.0-0" is modified', () async {
    // For the upper bound <3.0.0 is treated as <3.0.0-0, so they both have
    // the rewrite applied.
    await d.dir(appPath, [
      d.pubspec({
        'name': 'myapp',
        'environment': {'sdk': '>=2.12.0 <3.0.0-0'},
      }),
    ]).create();

    await pubGet(environment: {'_PUB_TEST_SDK_VERSION': '3.5.0'});
  });

  test('The bound of ">=3.0.0-dev <3.0.0" is not modified', () async {
    // When the lower bound is a dev release of 3.0.0 the upper bound is treated
    //  literally, and not converted to 3.0.0-0, therefore the rewrite to 4.0.0
    //  doesn't happen.
    await d.dir(appPath, [
      d.pubspec({
        'name': 'myapp',
        'environment': {'sdk': '>=3.0.0-dev <3.0.0'},
      }),
    ]).create();

    await pubGet(
      environment: {'_PUB_TEST_SDK_VERSION': '3.5.0'},
      error: contains(
        'Because myapp requires SDK version >=3.0.0-dev <3.0.0, '
        'version solving failed.',
      ),
    );
  });

  test('The bound of ">=2.12.0 <3.0.0" is not '
      'compatible with prereleases of dart 4', () async {
    await d.dir(appPath, [
      d.pubspec({
        'name': 'myapp',
        'environment': {'sdk': '>=2.12.0 <3.0.0'},
      }),
    ]).create();

    await pubGet(
      environment: {'_PUB_TEST_SDK_VERSION': '4.0.0-alpha'},
      error: contains(
        'Because myapp requires SDK version >=2.12.0 <4.0.0, '
        'version solving failed.',
      ),
    );
  });

  test(
    'When the constraint is not rewritten, a helpful hint is given',
    () async {
      await d
          .appDir(
            dependencies: {'foo': 'any'},
            pubspec: {
              'environment': {'sdk': '^2.12.0'},
            },
          )
          .create();
      final server = await servePackages();

      // foo is not null safe.
      server.serve(
        'foo',
        '1.0.0',
        pubspec: {
          'environment': {'sdk': '>=2.10.0 <3.0.0'},
        },
      );
      await pubGet(
        error: contains(
          'The lower bound of "sdk: \'>=2.10.0 <3.0.0\'" '
          'must be 2.12.0 or higher to enable null safety.'
          '\nFor details, see https://dart.dev/null-safety',
        ),
      );
    },
  );

  test('Rewrite only happens after Dart 3', () async {
    await d.dir(appPath, [
      d.pubspec({
        'name': 'myapp',
        'environment': {'sdk': '>=2.19.1 <3.0.0'},
      }),
    ]).create();

    await pubGet(
      error: contains(
        'Because myapp requires SDK version >=2.19.1 <3.0.0, '
        'version solving failed.',
      ),
      environment: {'_PUB_TEST_SDK_VERSION': '2.19.0'},
    );
  });
}
