// 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'},
    );
  });
}
