// Copyright (c) 2015, 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.

library pub_cache_test;

import 'dart:io';

import 'package:path/path.dart' as path;
import 'package:pub_cache/pub_cache.dart';
import 'package:test/test.dart';

void main() => defineTests();

void defineTests() {
  final String cacheDirName = Platform.isWindows ? 'Cache' : 'pub-cache';

  group('PubCache', () {
    tearDown(() {
      Directory cacheDir = PubCache.getSystemCacheLocation();
      var globalDir = new Directory(path.join(cacheDir.path, "global_packages"));
      var file = new File(path.join(globalDir.path, "nonsense"));
      if (file.existsSync()) {
        file.deleteSync();
      }
    });

    test('getSystemCacheLocation', () {
      Directory cacheDir = PubCache.getSystemCacheLocation();
      expect(cacheDir, isNotNull);
      expect(path.basename(cacheDir.path), contains(cacheDirName));
    });

    test('Create PubCache when non-directories are in global_packages', () {
      // Get cache in its current state
      var cache = new PubCache();
      var currentGlobalApps = cache.getGlobalApplications();

      // Put a file in global_packages
      Directory cacheDir = PubCache.getSystemCacheLocation();
      var globalDir = new Directory(path.join(cacheDir.path, "global_packages"));
      var file = new File(path.join(globalDir.path, "nonsense"));
      file.writeAsStringSync("pub_cache test suite");

      // Ensure that this file is not reflected in cache
      cache = new PubCache();
      var newGlobalApps = cache.getGlobalApplications();

      expect(currentGlobalApps.length, newGlobalApps.length);
    });

    test('PubCache', () {
      PubCache cache = new PubCache();
      expect(cache, isNotNull);
      expect(cache.location, isNotNull);
      expect(path.basename(cache.location.path), contains(cacheDirName));
    });

    test('getBinaries', () {
      PubCache cache = new PubCache();
      expect(cache.getBinScripts(), isNotNull);
    });

    test('getGlobalApplications', () {
      PubCache cache = new PubCache();
      expect(cache.getGlobalApplications(), isNotEmpty);
    });

    test('getPackageRefs', () {
      PubCache cache = new PubCache();
      expect(cache.getPackageRefs(), isNotEmpty);
    });

    test('getCachedPackages', () {
      PubCache cache = new PubCache();
      expect(cache.getCachedPackages(), isNotEmpty);
    });

    test('getAllPackageVersions', () {
      PubCache cache = new PubCache();
      expect(cache.getAllPackageVersions('path'), isNotEmpty);
    });

    test('getLatestVersion', () {
      PubCache cache = new PubCache();
      expect(cache.getLatestVersion('path'), isNotNull);
    });

    test('getLatestVersion.dev', () {
      PubCache cache = new PubCache();
      expect(cache.getLatestVersion('path', includePreRelease: true), isNotNull);
    });
  });

  group('Application', () {
    PubCache cache;
    Application app;

    setUp(() {
      cache = new PubCache();
      app = cache.getGlobalApplications().first;
    });

    test('name', () {
      expect(app.name, isNotEmpty);
    });

    test('version', () {
      expect(app.version, isNotNull);
    });

    test('getDefiningPackageRef', () {
      expect(app.getDefiningPackageRef().name, app.name);
    });

    test('getPackageRefs', () {
      expect(app.getPackageRefs(), isNotEmpty);
    });

    test('toString', () {
      expect(app.toString(), isNotEmpty);
    });
  });

  group('PackageRef', () {
    PubCache cache;
    Application app;
    PackageRef ref;

    setUp(() {
      cache = new PubCache();
      app = cache.getGlobalApplications().first;
      ref = app.getPackageRefs().first;
    });

    test('name', () {
      expect(ref.name, isNotEmpty);
    });

    test('==', () {
      PackageRef ref0 = app.getPackageRefs()[0];
      PackageRef ref1 = app.getPackageRefs()[1];

      expect(ref0, equals(ref0));
      expect(ref0, isNot(equals(ref1)));
    });

    test('resolve', () {
      expect(ref.resolve(), isNotNull);
    });

    test('toString', () {
      expect(ref.toString(), isNotEmpty);
    });
  });

  group('Package', () {
    test('toString', () {
      PubCache cache = new PubCache();
      Package p = cache.getPackageRefs().first.resolve();
      expect(p, isNotNull);
      expect(p.toString(), isNotEmpty);
    });
  });

  group('integration', () {
    test('list apps', () {
      StringBuffer buf = new StringBuffer();
      PubCache cache = new PubCache();
      var apps = cache.getGlobalApplications();
      apps.forEach((app) => buf.writeln('  ${app}'));
      expect(buf.toString(), isNotEmpty);
    });

    test('everything parses', () {
      StringBuffer buf = new StringBuffer();
      PubCache cache = new PubCache();
      var packageRefs = cache.getPackageRefs();
      packageRefs.forEach((ref) {
        expect(ref.version, isNotNull);
        buf.writeln('${ref}');
      });
      expect(buf.toString(), isNotEmpty);
    });

    test('list packages', () {
      StringBuffer buf = new StringBuffer();
      PubCache cache = new PubCache();
      var packages = cache.getCachedPackages();
      packages.forEach((pkg) {
        List<PackageRef> versions = cache.getAllPackageVersions(pkg);
        buf.writeln(
            '${pkg} [${versions.map((p) => p.version.toString()).join(', ')}]');
      });
      expect(buf.toString(), isNotEmpty);
    });

    test('everything resolves', () {
      PubCache cache = new PubCache();

      for (Application app in cache.getGlobalApplications()) {
        for (PackageRef ref in app.getPackageRefs()) {
          expect(ref.resolve(), isNotNull);
        }
      }

      for (PackageRef ref in cache.getPackageRefs()) {
        expect(ref.resolve(), isNotNull);
      }
    });
  });
}
