// 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({'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: 'bar',
            version: '3.2.1',
            languageVersion: '2.7',
          ),
          d.packageConfigEntry(
            name: 'baz',
            version: '2.2.2',
            languageVersion: '2.7',
          ),
          d.packageConfigEntry(
            name: 'myapp',
            path: '.',
            languageVersion: '0.1',
          ),
        ]),
      ]).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({'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: '2.7',
          ),
          d.packageConfigEntry(
            name: 'bar',
            version: '3.2.1',
            languageVersion: '2.7',
          ),
          d.packageConfigEntry(
            name: 'baz',
            version: '2.2.2',
            languageVersion: '2.7',
          ),
          d.packageConfigEntry(
            name: 'myapp',
            path: '.',
            languageVersion: '0.1',
          ),
        ]),
      ]).validate();
    });

    test('package_config.json file is not created if pub fails', () async {
      await d.dir(appPath, [
        d.appPubspec({'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.rawPubspec({
          '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: '2.7',
          ),
          d.packageConfigEntry(
            name: 'baz',
            path: '../local_baz',
            languageVersion: '2.7',
          ),
          d.packageConfigEntry(
            name: 'myapp',
            path: '.',
            languageVersion: '0.1',
          ),
        ]),
      ]).validate();
    });

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

      await d.dir(appPath, [
        d.pubspec({
          'name': 'myapp',
          'dependencies': {
            'foo': '^1.2.3',
          },
          'environment': {
            'sdk': '>=0.1.0 <=0.2.2+2', // tests runs with '0.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: '0.0',
          ),
          d.packageConfigEntry(
            name: 'myapp',
            path: '.',
            languageVersion: '0.1',
          ),
        ]),
      ]).validate();
    });

    test('package_config.json has 2.7 default language version', () async {
      final server = await servePackages();
      server.serve(
        'foo',
        '1.2.3',
        pubspec: {
          'environment': {
            'sdk': 'any',
          },
        },
        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: '0.1',
          ),
        ]),
      ]).validate();
    });
  });
}
