// Copyright (c) 2013, 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:http/http.dart';
import 'package:path/path.dart' as p;
import 'package:pub/src/exit_codes.dart';
import 'package:test/test.dart';

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

void main() {
  test('adds correct entries to cache and stores the content-hash', () async {
    final server = await servePackages();
    server.serve('foo', '1.0.0');
    server.serve('foo', '2.0.0');

    await appDir(dependencies: {'foo': '^2.0.0'}).create();
    // Do a `pub get` here to create a lock file in order to validate we later can
    // `pub get --offline` with packages installed by `preload`.
    await pubGet();

    await runPub(args: ['cache', 'clean', '-f']);

    final archivePath1 = p.join(sandbox, 'foo-1.0.0-archive.tar.gz');
    final archivePath2 = p.join(sandbox, 'foo-2.0.0-archive.tar.gz');

    File(archivePath1).writeAsBytesSync(await readBytes(
        Uri.parse(server.url).resolve('packages/foo/versions/1.0.0.tar.gz')));
    File(archivePath2).writeAsBytesSync(await readBytes(
        Uri.parse(server.url).resolve('packages/foo/versions/2.0.0.tar.gz')));
    await runPub(
      args: ['cache', 'preload', archivePath1, archivePath2],
      environment: {'_PUB_TEST_DEFAULT_HOSTED_URL': server.url},
      output: allOf(
        [
          contains('Installed $archivePath1 in cache as foo 1.0.0.'),
          contains('Installed $archivePath2 in cache as foo 2.0.0.'),
        ],
      ),
    );
    await d.cacheDir({'foo': '1.0.0'}).validate();
    await d.cacheDir({'foo': '2.0.0'}).validate();

    await hostedHashesCache([
      file('foo-1.0.0.sha256', await server.peekArchiveSha256('foo', '1.0.0')),
    ]).validate();

    await hostedHashesCache([
      file('foo-2.0.0.sha256', await server.peekArchiveSha256('foo', '2.0.0')),
    ]).validate();

    await pubGet(args: ['--offline']);
  });

  test(
      'installs package according to PUB_HOSTED_URL even on non-offical server',
      () async {
    final server = await servePackages();
    server.serve('foo', '1.0.0');

    final archivePath = p.join(sandbox, 'archive');

    File(archivePath).writeAsBytesSync(await readBytes(
        Uri.parse(server.url).resolve('packages/foo/versions/1.0.0.tar.gz')));
    await runPub(
      args: ['cache', 'preload', archivePath],
      // By having pub.dev be the "official" server the test-server (localhost)
      // is considered non-official. Test that the output mentions that we
      // are installing to a non-official server.
      environment: {'_PUB_TEST_DEFAULT_HOSTED_URL': 'pub.dev'},
      output: allOf([
        contains(
            'Installed $archivePath in cache as foo 1.0.0 from ${server.url}.')
      ]),
    );
    await d.cacheDir({'foo': '1.0.0'}).validate();
  });

  test('overwrites existing entry in cache', () async {
    final server = await servePackages();
    server.serve('foo', '1.0.0', contents: [file('old-file.txt')]);

    final archivePath = p.join(sandbox, 'archive');

    File(archivePath).writeAsBytesSync(
      await readBytes(
        Uri.parse(server.url).resolve('packages/foo/versions/1.0.0.tar.gz'),
      ),
    );
    await runPub(
      args: ['cache', 'preload', archivePath],
      environment: {'_PUB_TEST_DEFAULT_HOSTED_URL': server.url},
      output:
          allOf([contains('Installed $archivePath in cache as foo 1.0.0.')]),
    );

    server.serve('foo', '1.0.0', contents: [file('new-file.txt')]);

    File(archivePath).writeAsBytesSync(
      await readBytes(
        Uri.parse(server.url).resolve('packages/foo/versions/1.0.0.tar.gz'),
      ),
    );

    File(archivePath).writeAsBytesSync(
      await readBytes(
        Uri.parse(server.url).resolve('packages/foo/versions/1.0.0.tar.gz'),
      ),
    );

    await runPub(
      args: ['cache', 'preload', archivePath],
      environment: {'_PUB_TEST_DEFAULT_HOSTED_URL': server.url},
      output:
          allOf([contains('Installed $archivePath in cache as foo 1.0.0.')]),
    );
    await hostedCache([
      dir('foo-1.0.0', [file('new-file.txt'), nothing('old-file.txt')])
    ]).validate();
  });

  test('handles missing archive', () async {
    final archivePath = p.join(sandbox, 'archive');
    await runPub(
      args: ['cache', 'preload', archivePath],
      error: contains('Could not find file $archivePath.'),
      exitCode: 1,
    );
  });

  test('handles broken archives', () async {
    final archivePath = p.join(sandbox, 'archive');
    File(archivePath).writeAsBytesSync('garbage'.codeUnits);
    await runPub(
      args: ['cache', 'preload', archivePath],
      error:
          contains('Failed to extract `$archivePath`: Filter error, bad data.'),
      exitCode: DATA,
    );
  });

  test('handles missing pubspec.yaml in archive', () async {
    final archivePath = p.join(sandbox, 'archive');

    // Create a tar.gz with a single file (and no pubspec.yaml).
    File(archivePath).writeAsBytesSync(
      await tarFromDescriptors([d.file('foo.txt')]).expand((x) => x).toList(),
    );

    await runPub(
      args: ['cache', 'preload', archivePath],
      error: contains(
        'Found no `pubspec.yaml` in $archivePath. Is it a valid pub package archive?',
      ),
      exitCode: 1,
    );
  });

  test('handles broken pubspec.yaml in archive', () async {
    final archivePath = p.join(sandbox, 'archive');

    File(archivePath).writeAsBytesSync(
        await tarFromDescriptors([d.file('pubspec.yaml', '{}')])
            .expand((x) => x)
            .toList());

    await runPub(
      args: ['cache', 'preload', archivePath],
      error: contains(
        'Failed to load `pubspec.yaml` from `$archivePath`: Error on line 1, column 1',
      ),
      exitCode: 1,
    );
  });
}
