// Copyright (c) 2022, 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';

import 'package:path/path.dart' as p;
import 'package:pub/src/exit_codes.dart';
import 'package:test/test.dart';

import '../descriptor.dart';
import '../test_pub.dart';

Future<void> main() async {
  test('Recreates .dart_tool/package_config.json, redownloads archives',
      () async {
    final server = await servePackages();
    server.serve('foo', '1.0.0');
    await appDir(dependencies: {'foo': 'any'}).create();
    await pubGet();
    final packageConfig =
        File(path(p.join(appPath, '.dart_tool', 'package_config.json')));
    packageConfig.deleteSync();
    await runPub(args: ['cache', 'clean', '-f']);
    await pubGet(args: ['--enforce-lockfile']);
    expect(packageConfig.existsSync(), isTrue);
    await cacheDir({'foo': '1.0.0'}).validate();
    await appPackageConfigFile([
      packageConfigEntry(name: 'foo', version: '1.0.0'),
    ]).validate();
  });

  test('Refuses to get if no lockfile exists', () async {
    await appDir(dependencies: {}).create();
    await pubGet(
      args: ['--enforce-lockfile'],
      error: '''
Retrieving dependencies failed.
Cannot do `--enforce-lockfile` without an existing `pubspec.lock`.

Try running `dart pub get` to create `pubspec.lock`.
''',
    );
  });

  test('Refuses to get in ./example if hash is updated', () async {
    final server = await servePackages();
    server.serveContentHashes = true;
    server.serve('foo', '1.0.0');
    server.serve('bar', '1.0.0');

    await appDir(dependencies: {'foo': '^1.0.0'}).create();
    await dir(appPath, [
      dir('example', [
        libPubspec(
          'example',
          '0.0.0',
          deps: {
            'bar': '1.0.0',
            'myapp': {'path': '../'}
          },
        )
      ])
    ]).create();
    await pubGet(args: ['--example']);

    server.serve(
      'bar',
      '1.0.0',
      contents: [
        file('README.md', 'Including this will change the content-hash.'),
      ],
    );
    // Deleting the version-listing cache will cause it to be refetched, and the
    // error will happen.
    File(p.join(globalServer.cachingPath, '.cache', 'bar-versions.json'))
        .deleteSync();

    final example = p.join('.', 'example');
    final examplePubspec = p.join('example', 'pubspec.yaml');
    final exampleLockfile = p.join('example', 'pubspec.lock');

    await pubGet(
      args: ['--enforce-lockfile', '--example'],
      output: allOf(
        contains('Got dependencies!'),
        contains('Resolving dependencies in $example...'),
      ),
      error: contains(
        'Unable to satisfy `$examplePubspec` using `$exampleLockfile` in $example. For details run `dart pub get --directory $example --enforce-lockfile',
      ),
      exitCode: DATA,
    );
  });

  test('Refuses to get if lockfile is missing package', () async {
    final server = await servePackages();
    server.serve('foo', '1.0.0');
    await appDir(dependencies: {}).create();
    await pubGet();
    await appDir(dependencies: {'foo': 'any'}).create();

    await pubGet(
      args: ['--enforce-lockfile'],
      output: allOf(
        contains('+ foo 1.0.0'),
        contains('Would have changed 1 dependency.'),
      ),
      error: contains('Unable to satisfy `pubspec.yaml` using `pubspec.lock`.'),
      exitCode: DATA,
    );
  });

  test('Refuses to get if package is locked to version not matching constraint',
      () async {
    final server = await servePackages();
    server.serve('foo', '1.0.0');
    server.serve('foo', '2.0.0');
    await appDir(dependencies: {'foo': '^1.0.0'}).create();
    await pubGet();
    await appDir(dependencies: {'foo': '^2.0.0'}).create();
    await pubGet(
      args: ['--enforce-lockfile'],
      output: allOf([
        contains('> foo 2.0.0 (was 1.0.0)'),
        contains('Would have changed 1 dependency.'),
      ]),
      error: contains('Unable to satisfy `pubspec.yaml` using `pubspec.lock`.'),
      exitCode: DATA,
    );
  });

  test("Refuses to get if hash on server doesn't correspond to lockfile",
      () async {
    final server = await servePackages();
    server.serveContentHashes = true;
    server.serve('foo', '1.0.0');
    await appDir(dependencies: {'foo': '^1.0.0'}).create();
    await pubGet();
    server.serve(
      'foo',
      '1.0.0',
      contents: [
        file('README.md', 'Including this will change the content-hash.'),
      ],
    );
    // Deleting the version-listing cache will cause it to be refetched, and the
    // error will happen.
    File(p.join(globalServer.cachingPath, '.cache', 'foo-versions.json'))
        .deleteSync();
    await pubGet(
      args: ['--enforce-lockfile'],
      output: allOf(
        contains('~ foo 1.0.0 (was 1.0.0)'),
        contains('Would have changed 1 dependency.'),
      ),
      error: allOf(
        contains('Cached version of foo-1.0.0 has wrong hash - redownloading.'),
        contains(
          'The existing content-hash from pubspec.lock doesn\'t match contents for:',
        ),
        contains(
          ' * foo-1.0.0 from "${server.url}"',
        ),
        contains(
          'Unable to satisfy `pubspec.yaml` using `pubspec.lock`.',
        ),
      ),
      exitCode: DATA,
    );
  });

  test(
      'Refuses to get if archive on legacy server doesn\'t have hash corresponding to lockfile',
      () async {
    final server = await servePackages();
    server.serveContentHashes = false;
    server.serve('foo', '1.0.0');
    await appDir(dependencies: {'foo': '^1.0.0'}).create();
    await pubGet();
    await runPub(args: ['cache', 'clean', '-f']);
    server.serve(
      'foo',
      '1.0.0',
      contents: [
        file('README.md', 'Including this will change the content-hash.'),
      ],
    );

    await pubGet(
      args: ['--enforce-lockfile'],
      output: allOf(
        contains('~ foo 1.0.0 (was 1.0.0)'),
        contains('Would have changed 1 dependency.'),
      ),
      error: allOf(
        contains('''
The existing content-hash from pubspec.lock doesn't match contents for:
 * foo-1.0.0 from "${server.url}"'''),
        contains('Unable to satisfy `pubspec.yaml` using `pubspec.lock`.'),
      ),
      exitCode: DATA,
    );
  });
}
