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

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

void main() {
  group('root-level packages', () {
    setUp(() async {
      // Create two cached revisions of foo.
      await d.git(
        'foo.git',
        [d.libDir('foo'), d.libPubspec('foo', '1.0.0')],
      ).create();

      await d.appDir(
        dependencies: {
          'foo': {'git': '../foo.git'},
        },
      ).create();
      await pubGet();

      await d.git(
        'foo.git',
        [d.libDir('foo'), d.libPubspec('foo', '1.0.1')],
      ).commit();

      await pubUpgrade();
    });

    test('reinstalls previously cached git packages', () async {
      // Find the cached foo packages for each revision.
      var gitCacheDir = path.join(d.sandbox, cachePath, 'git');
      var fooDirs = listDir(gitCacheDir)
          .where((dir) => path.basename(dir).startsWith('foo-'))
          .toList();

      // Delete "foo.dart" from them.
      for (var dir in fooDirs) {
        deleteEntry(path.join(dir, 'lib', 'foo.dart'));
      }

      // Repair them.
      await runPub(
        args: ['cache', 'repair'],
        output: '''
          Resetting Git repository for foo 1.0.0...
          Resetting Git repository for foo 1.0.1...
          Reinstalled 2 packages.''',
      );

      // The missing libraries should have been replaced.
      var fooLibs = fooDirs.map((dir) {
        var fooDirName = path.basename(dir);
        return d.dir(fooDirName, [
          d.dir('lib', [d.file('foo.dart', 'main() => "foo";')]),
        ]);
      }).toList();

      await d.dir(cachePath, [d.dir('git', fooLibs)]).validate();
    });

    test('deletes packages without pubspecs', () async {
      var gitCacheDir = path.join(d.sandbox, cachePath, 'git');
      var fooDirs = listDir(gitCacheDir)
          .where((dir) => path.basename(dir).startsWith('foo-'))
          .toList();

      for (var dir in fooDirs) {
        deleteEntry(path.join(dir, 'pubspec.yaml'));
      }

      await runPub(
        args: ['cache', 'repair'],
        error: allOf([
          contains('Failed to load package:'),
          contains('Could not find a file named "pubspec.yaml" in '),
          contains('foo-'),
        ]),
        output: allOf([
          startsWith('Failed to reinstall 2 packages:'),
          contains('- foo 0.0.0 from git'),
          contains('- foo 0.0.0 from git'),
        ]),
        exitCode: exit_codes.UNAVAILABLE,
      );

      await d.dir(cachePath, [
        d.dir('git', fooDirs.map((dir) => d.nothing(path.basename(dir)))),
      ]).validate();
    });

    test('deletes packages with invalid pubspecs', () async {
      var gitCacheDir = path.join(d.sandbox, cachePath, 'git');
      var fooDirs = listDir(gitCacheDir)
          .where((dir) => path.basename(dir).startsWith('foo-'))
          .toList();

      for (var dir in fooDirs) {
        writeTextFile(path.join(dir, 'pubspec.yaml'), '{');
      }

      await runPub(
        args: ['cache', 'repair'],
        error: allOf([
          contains('Failed to load package:'),
          contains('Error on line 1, column 2 of '),
          contains('foo-'),
        ]),
        output: allOf([
          startsWith('Failed to reinstall 2 packages:'),
          contains('- foo 0.0.0 from git'),
          contains('- foo 0.0.0 from git'),
        ]),
        exitCode: exit_codes.UNAVAILABLE,
      );

      await d.dir(cachePath, [
        d.dir('git', fooDirs.map((dir) => d.nothing(path.basename(dir)))),
      ]).validate();
    });
  });

  group('subdirectory packages', () {
    setUp(() async {
      // Create two cached revisions of foo.
      await d.git('foo.git', [
        d.dir('subdir', [d.libDir('sub'), d.libPubspec('sub', '1.0.0')]),
      ]).create();

      await d.appDir(
        dependencies: {
          'sub': {
            'git': {'url': '../foo.git', 'path': 'subdir'},
          },
        },
      ).create();
      await pubGet();

      await d.git('foo.git', [
        d.dir('subdir', [d.libDir('sub'), d.libPubspec('sub', '1.0.1')]),
      ]).commit();

      await pubUpgrade();
    });

    test('reinstalls previously cached git packages', () async {
      // Find the cached foo packages for each revision.
      var gitCacheDir = path.join(d.sandbox, cachePath, 'git');
      var fooDirs = listDir(gitCacheDir)
          .where((dir) => path.basename(dir).startsWith('foo-'))
          .toList();

      // Delete "sub.dart" from them.
      for (var dir in fooDirs) {
        deleteEntry(path.join(dir, 'subdir/lib/sub.dart'));
      }

      // Repair them.
      await runPub(
        args: ['cache', 'repair'],
        output: '''
          Resetting Git repository for sub 1.0.0...
          Resetting Git repository for sub 1.0.1...
          Reinstalled 2 packages.''',
      );

      // The missing libraries should have been replaced.
      var fooLibs = fooDirs.map((dir) {
        var fooDirName = path.basename(dir);
        return d.dir(fooDirName, [
          d.dir('subdir', [
            d.dir('lib', [d.file('sub.dart', 'main() => "sub";')]),
          ]),
        ]);
      }).toList();

      await d.dir(cachePath, [d.dir('git', fooLibs)]).validate();
    });

    test('deletes packages without pubspecs', () async {
      var gitCacheDir = path.join(d.sandbox, cachePath, 'git');
      var fooDirs = listDir(gitCacheDir)
          .where((dir) => path.basename(dir).startsWith('foo-'))
          .toList();

      for (var dir in fooDirs) {
        deleteEntry(path.join(dir, 'subdir', 'pubspec.yaml'));
      }

      await runPub(
        args: ['cache', 'repair'],
        error: allOf([
          contains('Failed to load package:'),
          contains('Could not find a file named "pubspec.yaml" in '),
          contains('foo-'),
          contains('${path.separator}subdir'),
        ]),
        output: allOf([
          startsWith('Failed to reinstall 2 packages:'),
          contains('- foo 0.0.0 from git'),
          contains('- foo 0.0.0 from git'),
        ]),
        exitCode: exit_codes.UNAVAILABLE,
      );

      await d.dir(cachePath, [
        d.dir('git', fooDirs.map((dir) => d.nothing(path.basename(dir)))),
      ]).validate();
    });
  });
}
