// 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 '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('cannot use both --path and --git-<option> flags', () async {
    ensureGit();

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

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

    await pubAdd(
      args: ['foo', '--git-url', '../foo.git', '--path', '../bar'],
      error: allOf([
        contains('Packages can only have one source, pub add flags '
            '"--git-url" and "--path" are'),
        contains('conflicting.'),
      ]),
      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('cannot use both --path and --host-<option> flags', () async {
    // Make the default server serve errors. Only the custom server should
    // be accessed.
    (await servePackages()).serveErrors();

    final server = await startPackageServer();
    server.serve('foo', '1.2.3');

    await d
        .dir('bar', [d.libDir('bar'), d.libPubspec('foo', '0.0.1')]).create();
    await d.appDir(dependencies: {}).create();

    await pubAdd(
      args: [
        'foo',
        '--hosted-url',
        'http://localhost:${server.port}',
        '--path',
        '../bar',
      ],
      error: allOf([
        contains('Packages can only have one source, pub add flags '
            '"--hosted-url" and "--path" are'),
        contains('conflicting.'),
      ]),
      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('cannot use both --hosted-url and --git-<option> flags', () async {
    // Make the default server serve errors. Only the custom server should
    // be accessed.
    (await servePackages()).serveErrors();

    final server = await startPackageServer();
    server.serve('foo', '1.2.3');

    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',
        '--hosted-url',
        'http://localhost:${server.port}',
        '--git-url',
        '../foo.git',
      ],
      error: allOf([
        contains('Packages can only have one source, pub add flags '
            '"--git-url" and "--hosted-url"'),
        contains('are conflicting.'),
      ]),
      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();
  });
}
