// Copyright (c) 2015, 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' as exit_codes;

import 'package:test/test.dart';

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

void main() {
  forBothPubGetAndUpgrade((command) {
    test('package_config.json file is created', () async {
      await servePackages()
        ..serve(
          'foo',
          '1.2.3',
          deps: {'baz': '2.2.2'},
          contents: [d.dir('lib', [])],
        )
        ..serve('bar', '3.2.1', contents: [d.dir('lib', [])])
        ..serve(
          'baz',
          '2.2.2',
          deps: {'bar': '3.2.1'},
          contents: [d.dir('lib', [])],
        );

      await d.dir(appPath, [
        d.appPubspec(dependencies: {'foo': '1.2.3'}),
        d.dir('lib'),
      ]).create();

      await pubCommand(command);

      await d.dir(appPath, [
        d.packageConfigFile([
          d.packageConfigEntry(
            name: 'foo',
            version: '1.2.3',
            languageVersion: '3.0',
          ),
          d.packageConfigEntry(
            name: 'bar',
            version: '3.2.1',
            languageVersion: '3.0',
          ),
          d.packageConfigEntry(
            name: 'baz',
            version: '2.2.2',
            languageVersion: '3.0',
          ),
          d.packageConfigEntry(
            name: 'myapp',
            path: '.',
            languageVersion: '3.0',
          ),
        ]),
      ]).validate();
    });

    test('package_config.json file is overwritten', () async {
      await servePackages()
        ..serve(
          'foo',
          '1.2.3',
          deps: {'baz': '2.2.2'},
          contents: [d.dir('lib', [])],
        )
        ..serve('bar', '3.2.1', contents: [d.dir('lib', [])])
        ..serve(
          'baz',
          '2.2.2',
          deps: {'bar': '3.2.1'},
          contents: [d.dir('lib', [])],
        );

      await d.dir(appPath, [
        d.appPubspec(dependencies: {'foo': '1.2.3'}),
        d.dir('lib'),
      ]).create();

      final oldFile = d.dir(appPath, [
        d.packageConfigFile([
          d.packageConfigEntry(
            name: 'notFoo',
            version: '9.9.9',
            languageVersion: '2.7',
          ),
        ]),
      ]);
      await oldFile.create();
      await oldFile.validate(); // Sanity-check that file was created correctly.

      await pubCommand(command);

      await d.dir(appPath, [
        d.packageConfigFile([
          d.packageConfigEntry(
            name: 'foo',
            version: '1.2.3',
            languageVersion: '3.0',
          ),
          d.packageConfigEntry(
            name: 'bar',
            version: '3.2.1',
            languageVersion: '3.0',
          ),
          d.packageConfigEntry(
            name: 'baz',
            version: '2.2.2',
            languageVersion: '3.0',
          ),
          d.packageConfigEntry(
            name: 'myapp',
            path: '.',
            languageVersion: '3.0',
          ),
        ]),
      ]).validate();
    });

    test('package_config.json file is not created if pub fails', () async {
      await d.dir(appPath, [
        d.appPubspec(dependencies: {'foo': '1.2.3'}),
        d.dir('lib'),
      ]).create();

      await pubCommand(
        command,
        args: ['--offline'],
        error: equalsIgnoringWhitespace("""
            Because myapp depends on foo any which doesn't exist (could not find
              package foo in cache), version solving failed.

            Try again without --offline!
          """),
        exitCode: exit_codes.UNAVAILABLE,
      );

      await d.dir(appPath, [
        d.nothing('.dart_tool/package_config.json'),
      ]).validate();
    });

    test(
        '.dart_tool/package_config.json file has relative path to path dependency',
        () async {
      await servePackages()
        ..serve(
          'foo',
          '1.2.3',
          deps: {'baz': 'any'},
          contents: [d.dir('lib', [])],
        )
        ..serve('baz', '9.9.9', deps: {}, contents: [d.dir('lib', [])]);

      await d.dir('local_baz', [
        d.libDir('baz', 'baz 3.2.1'),
        d.pubspec({
          'name': 'baz',
          'version': '3.2.1',
        }),
      ]).create();

      await d.dir(appPath, [
        d.pubspec({
          'name': 'myapp',
          'dependencies': {
            'foo': '^1.2.3',
          },
          'dependency_overrides': {
            'baz': {'path': '../local_baz'},
          },
        }),
        d.dir('lib'),
      ]).create();

      await pubCommand(command);

      await d.dir(appPath, [
        d.packageConfigFile([
          d.packageConfigEntry(
            name: 'foo',
            version: '1.2.3',
            languageVersion: '3.0',
          ),
          d.packageConfigEntry(
            name: 'baz',
            path: '../local_baz',
            languageVersion: '3.0',
          ),
          d.packageConfigEntry(
            name: 'myapp',
            path: '.',
            languageVersion: '3.0',
          ),
        ]),
      ]).validate();
    });

    test('package_config.json has language version', () async {
      final server = await servePackages();
      server.serve(
        'foo',
        '1.2.3',
        pubspec: {
          'environment': {
            'sdk': '>=3.0.1 <=3.2.2+2', // tests runs with '3.1.2+3'
          },
        },
        contents: [d.dir('lib', [])],
      );

      await d.dir(appPath, [
        d.pubspec({
          'name': 'myapp',
          'dependencies': {
            'foo': '^1.2.3',
          },
          'environment': {
            'sdk': '>=3.1.0 <=3.2.2+2', // tests runs with '3.1.2+3'
          },
        }),
        d.dir('lib'),
      ]).create();

      await pubCommand(command);

      await d.dir(appPath, [
        d.packageConfigFile([
          d.packageConfigEntry(
            name: 'foo',
            version: '1.2.3',
            languageVersion: '3.0',
          ),
          d.packageConfigEntry(
            name: 'myapp',
            path: '.',
            languageVersion: '3.1',
          ),
        ]),
      ]).validate();
    });

    test('package_config.json has 2.7 default language version', () async {
      // TODO(sigurdm): Reconsider the default language version for dart 3.
      final server = await servePackages();
      server.serve(
        'foo',
        '1.2.3',
        pubspec: {
          'environment': {
            'sdk': '<4.0.0',
          },
        },
        contents: [d.dir('lib', [])],
      );

      await d.dir(appPath, [
        d.pubspec({
          'name': 'myapp',
          'dependencies': {
            'foo': '^1.2.3',
          },
        }),
        d.dir('lib'),
      ]).create();

      await pubCommand(command);

      await d.dir(appPath, [
        d.packageConfigFile([
          d.packageConfigEntry(
            name: 'foo',
            version: '1.2.3',
            languageVersion: '2.7',
          ),
          d.packageConfigEntry(
            name: 'myapp',
            path: '.',
            languageVersion: '3.0',
          ),
        ]),
      ]).validate();
    });
  });
}
