// 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.

@TestOn('vm')
library;

import 'package:path/path.dart' as p;
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('path dependency with absolute path', () async {
    await d.dir('foo', [
      d.libDir('foo'),
      d.libPubspec('foo', '0.0.1'),
    ]).create();

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

    final absolutePath = p.join(d.sandbox, 'foo');

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

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

    await d
        .appDir(
          dependencies: {
            'foo': {'path': absolutePath},
          },
        )
        .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();
    final absolutePath = p.join(d.sandbox, 'foo');

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

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

  test('fails when adding multiple packages through local path', () async {
    ensureGit();

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

    await d.appDir(dependencies: {}).create();
    final absolutePath = p.join(d.sandbox, 'foo');

    await pubAdd(
      args: ['foo:2.0.0', 'bar:0.1.3', 'baz:1.3.1', '--path', absolutePath],
      error: contains('--path cannot be used with multiple packages.'),
      exitCode: exit_codes.USAGE,
    );

    await d.appDir(dependencies: {}).validate();
    await d.dir(appPath, [
      d.nothing('.dart_tool/package_config.json'),
      d.nothing('pubspec.lock'),
    ]).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();
    final absolutePath = p.join(d.sandbox, 'foo');

    await pubAdd(
      args: ['foo:2.0.0', '--path', absolutePath],
      error: equalsIgnoringWhitespace(
        'Because myapp depends on foo from path which doesn\'t exist '
        '(could not find package foo at "$absolutePath"), 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('fails if path does not exist', () async {
    await d.appDir(dependencies: {}).create();

    final absolutePath = p.join(d.sandbox, 'foo');

    await pubAdd(
      args: ['foo', '--path', absolutePath],
      error: equalsIgnoringWhitespace(
        'Because myapp depends on foo from path which doesn\'t exist '
        '(could not find package foo at "$absolutePath"), 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();

    final absolutePath = p.join(d.sandbox, 'foo');
    await pubAdd(args: ['foo', '--path', absolutePath]);

    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': absolutePath},
        },
        'dependency_overrides': {'foo': '1.2.2'},
      }),
    ]).validate();
  });
}
