// 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 pubcache;

import 'dart:io';

import 'package:path/path.dart' as path;
import 'package:pub_semver/pub_semver.dart';
import 'package:yaml/yaml.dart' as yaml;

// TODO: do things like get all the versions for a package?

// TODO: get the latest version for a package?

// TODO: get the latest non-dev version for a package?

// TODO: get all the packages (id's only) in the pubcache

/**
 * TODO:
 */
class PubCache {

  static Directory getSystemCacheLocation() {
    if (Platform.environment.containsKey('PUB_CACHE')) {
      return new Directory(Platform.environment['PUB_CACHE']);
    } else if (Platform.operatingSystem == 'windows') {
      var appData = Platform.environment['APPDATA'];
      return new Directory(path.join(appData, 'Pub', 'Cache'));
    } else {
      return new Directory('${Platform.environment['HOME']}/.pub-cache');
    }
  }

  final Directory location;

  List<Application> _applications;
  List<PackageRef> _packageRefs;

  PubCache([Directory dir]) :
      location = dir == null ? getSystemCacheLocation() : dir {
    _parse();
  }

  /**
   * Return the contents of `bin/` - the scripts for the activated applications.
   */
  List<File> getBinaries() {
    Directory dir = _getSubDir(location, 'bin');
    return dir.existsSync() ? dir.listSync() : [];
  }

  List<Application> getGlobalApplications() => _applications;

  List<PackageRef> getPackageRefs() => _packageRefs;

  void _parse() {
    // Read the activated applications.
    _applications = [];

    Directory globalPackagesDir = _getSubDir(location, 'global_packages');
    if (globalPackagesDir.existsSync()) {
      _applications = globalPackagesDir.listSync().map(
          (dir) => new Application._(this, dir)).toList();
    }

    // TODO: Scan for git packages.

    // Scan hosted packages - just pub.dartlang.org for now.
    _packageRefs = [];

    Directory dartlangDir = new Directory(
        path.join(location.path, 'hosted', 'pub.dartlang.org'));
    if (dartlangDir.existsSync()) {
      _packageRefs = dartlangDir.listSync()
          .where((dir) => dir is Directory)
          .map((dir) => new _DirectoryPackageRef('hosted', dir))
          .toList();
    }
  }

  Directory _getSubDir(Directory dir, String name) =>
      new Directory(path.join(dir.path, name));
}

class Application {
  final PubCache _cache;
  final Directory _dir;

  List<PackageRef> _packageRefs;
  Version _version;

  Application._(this._cache, this._dir);

  String get name => path.basename(_dir.path);

  Version get version {
    if (_packageRefs == null) _parsePubspec();
    return _version;
  }

  List<PackageRef> getPackageRefs() {
    if (_packageRefs == null) _parsePubspec();
    return _packageRefs;
  }

  String toString() => '${name} ${version}';

  void _parsePubspec() {
    File pubspecLock = new File(path.join(_dir.path, 'pubspec.lock'));
    Map doc = yaml.loadYaml(pubspecLock.readAsStringSync());
    Map packages = doc['packages'];
    _packageRefs = packages.keys.map((key) {
      Map m = packages[key];
      return new _AppPackageRef(_cache, m['source'], key, m['version']);
    }).toList();

    String name = this.name;

    for (PackageRef ref in _packageRefs) {
      if (ref.name == name) {
        _version = ref.version;
        break;
      }
    }
  }
}

abstract class PackageRef {
  String get sourceType;
  String get name;
  Version get version;

  Package resolve();

  bool operator ==(other) {
    return this.sourceType == other.sourceType
        && this.name == other.name
        && this.version == other.version;
  }

  String toString() => '${name} ${version}';
}

class _AppPackageRef extends PackageRef {
  final PubCache cache;
  final String sourceType;
  final String name;
  final Version version;

  _AppPackageRef(this.cache, this.sourceType, this.name, String ver) :
      version = new Version.parse(ver);

  Package resolve() {
    for (PackageRef ref in cache.getPackageRefs()) {
      if (ref == this) return ref.resolve();
    }

    return null;
  }
}

class _DirectoryPackageRef extends PackageRef {
  final String sourceType;
  final Directory directory;

  String _name;
  Version _version;

  _DirectoryPackageRef(this.sourceType, this.directory) {
    _name = path.basename(this.directory.path);

    int index = _name.indexOf('-');
    if (index != -1) {
      _version = new Version.parse(_name.substring(index + 1));
      _name = _name.substring(0, index);
    }
  }

  String get name => _name;
  Version get version => _version;

  Package resolve() => new Package(directory, name, version);
}

class Package {
  final Directory location;
  final String name;
  final Version version;

  Package(this.location, this.name, this.version);

  String toString() => '${name} ${version}';
}
