// 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();

      var 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();
    });
  });
}
