// 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 'dart:io' show Platform;

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() {
  test('can use relative path', () async {
    await d
        .dir('foo', [d.libDir('foo'), d.libPubspec('foo', '0.0.1')]).create();

    await d.appDir(dependencies: {}).create();

    await pubAdd(args: ['foo', '--path', '../foo']);

    await d.appPackageConfigFile([
      d.packageConfigEntry(name: 'foo', path: '../foo'),
    ]).validate();

    await d.appDir(
      dependencies: {
        'foo': {'path': '../foo'},
      },
    ).validate();
  });

  test('can use relative path with a path descriptor', () async {
    await d
        .dir('foo', [d.libDir('foo'), d.libPubspec('foo', '1.2.3')]).create();

    await d.appDir().create();

    await pubAdd(
      args: ['dev:foo:{"path":"../foo"}'],
    );

    await d.dir(appPath, [
      d.pubspec({
        'name': 'myapp',
        'dev_dependencies': {
          'foo': {'path': '../foo'},
        },
      }),
    ]).validate();
  });

  test('can use relative path with --directory', () async {
    await d
        .dir('foo', [d.libDir('foo'), d.libPubspec('foo', '0.0.1')]).create();

    await d.appDir(dependencies: {}).create();

    await pubAdd(
      args: ['--directory', appPath, 'foo', '--path', 'foo'],
      workingDirectory: d.sandbox,
      output: contains('Changed 1 dependency in `myapp`!'),
    );

    await d.appPackageConfigFile([
      d.packageConfigEntry(name: 'foo', path: '../foo'),
    ]).validate();

    await d.appDir(
      dependencies: {
        'foo': {'path': '../foo'},
      },
    ).validate();
  });

  test('fails if path does not exist', () async {
    await d.appDir(dependencies: {}).create();

    await pubAdd(
      args: ['foo', '--path', '../foo'],
      error: equalsIgnoringWhitespace(
          'Because myapp depends on foo from path which doesn\'t exist '
          '(could not find package foo at "..${Platform.pathSeparator}foo"), '
          'version solving failed.'),
      exitCode: exit_codes.DATA,
    );

    await d.appDir(dependencies: {}).validate();
    await d.dir(appPath, [
      d.nothing('.dart_tool/package_config.json'),
      d.nothing('pubspec.lock'),
    ]).validate();
  });

  test('adds a package from absolute path with version constraint', () async {
    await d
        .dir('foo', [d.libDir('foo'), d.libPubspec('foo', '0.0.1')]).create();

    await d.appDir(dependencies: {}).create();

    await pubAdd(args: ['foo:0.0.1', '--path', '../foo']);

    await d.appDir(
      dependencies: {
        'foo': {'path': '../foo', 'version': '0.0.1'},
      },
    ).validate();
  });

  test('fails when adding with an invalid version constraint', () async {
    ensureGit();

    await d.git(
      'foo.git',
      [d.libDir('foo'), d.libPubspec('foo', '1.0.0')],
    ).create();

    await d.appDir(dependencies: {}).create();

    await pubAdd(
      args: ['foo:2.0.0', '--path', '../foo'],
      error: equalsIgnoringWhitespace(
          'Because myapp depends on foo from path which doesn\'t exist '
          '(could not find package foo at "..${Platform.pathSeparator}foo"), '
          'version solving failed.'),
      exitCode: exit_codes.DATA,
    );

    await d.appDir(dependencies: {}).validate();
    await d.dir(appPath, [
      d.nothing('.dart_tool/package_config.json'),
      d.nothing('pubspec.lock'),
    ]).validate();
  });

  test('can be overriden by dependency override', () async {
    final server = await servePackages();
    server.serve('foo', '1.2.2');
    await d
        .dir('foo', [d.libDir('foo'), d.libPubspec('foo', '0.0.1')]).create();

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

    await pubAdd(args: ['foo', '--path', '../foo']);

    await d.cacheDir({'foo': '1.2.2'}).validate();
    await d.appPackageConfigFile([
      d.packageConfigEntry(name: 'foo', version: '1.2.2'),
    ]).validate();
    await d.dir(appPath, [
      d.pubspec({
        'name': 'myapp',
        'dependencies': {
          'foo': {'path': '../foo'},
        },
        'dependency_overrides': {'foo': '1.2.2'},
      }),
    ]).validate();
  });

  test('Can add multiple path packages using descriptors', () async {
    await d
        .dir('foo', [d.libDir('foo'), d.libPubspec('foo', '0.0.1')]).create();
    await d
        .dir('bar', [d.libDir('bar'), d.libPubspec('bar', '0.0.1')]).create();

    await d.appDir(dependencies: {}).create();

    await pubAdd(
      args: [
        '--directory',
        appPath,
        'foo:{"path":"foo"}',
        'bar:{"path":"bar"}',
      ],
      workingDirectory: d.sandbox,
      output: contains('Changed 2 dependencies in `myapp`!'),
    );

    await d.appPackageConfigFile([
      d.packageConfigEntry(name: 'foo', path: '../foo'),
      d.packageConfigEntry(name: 'bar', path: '../bar'),
    ]).validate();

    await d.appDir(
      dependencies: {
        'foo': {'path': '../foo'},
        'bar': {'path': '../bar'},
      },
    ).validate();
  });
}
