// Copyright (c) 2012, 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 hosted_source;

import 'dart:io' as io;
import 'dart:json';
import 'dart:uri';

import 'io.dart';
import 'package.dart';
import 'pubspec.dart';
import 'source.dart';
import 'source_registry.dart';
import 'utils.dart';
import 'version.dart';

/**
 * A package source that installs packages from a package hosting site that
 * uses the same API as pub.dartlang.org.
 */
class HostedSource extends Source {
  final name = "hosted";
  final shouldCache = true;

  /**
   * The URL of the default package repository.
   */
  static final defaultUrl = "http://pub.dartlang.org";

  /**
   * Downloads a list of all versions of a package that are available from the
   * site.
   */
  Future<List<Version>> getVersions(String name, description) {
    var parsed = _parseDescription(description);
    var fullUrl = "${parsed.last}/packages/${parsed.first}.json";

    return httpGetString(fullUrl).transform((body) {
      var doc = JSON.parse(body);
      return doc['versions'].map((version) => new Version.parse(version));
    }).transformException((ex) {
      _throwFriendlyError(ex, parsed.first, parsed.last);
    });
  }

  /**
   * Downloads and parses the pubspec for a specific version of a package that
   * is available from the site.
   */
  Future<Pubspec> describe(PackageId id) {
    var parsed = _parseDescription(id.description);
    var fullUrl = "${parsed.last}/packages/${parsed.first}/versions/"
      "${id.version}.yaml";

    return httpGetString(fullUrl).transform((yaml) {
      return new Pubspec.parse(yaml, systemCache.sources);
    }).transformException((ex) {
      _throwFriendlyError(ex, id, parsed.last);
    });
  }

  /**
   * Downloads a package from the site and unpacks it.
   */
  Future<bool> install(PackageId id, String destPath) {
    var parsedDescription = _parseDescription(id.description);
    var name = parsedDescription.first;
    var url = parsedDescription.last;

    var fullUrl = "$url/packages/$name/versions/${id.version}.tar.gz";

    print('Downloading $id...');

    // Download and extract the archive to a temp directory.
    var tempDir;
    return Futures.wait([httpGet(fullUrl),
                         systemCache.createTempDir()]).chain((args) {
      tempDir = args[1];
      return timeout(extractTarGz(args[0], tempDir), HTTP_TIMEOUT,
          'Timed out while fetching URL "$fullUrl".');
    }).chain((_) {
      // Now that the install has succeeded, move it to the real location in
      // the cache. This ensures that we don't leave half-busted ghost
      // directories in the user's pub cache if an install fails.
      return renameDir(tempDir, destPath);
    }).transform((_) => true);
  }

  /**
   * The system cache directory for the hosted source contains subdirectories
   * for each separate repository URL that's used on the system. Each of these
   * subdirectories then contains a subdirectory for each package installed
   * from that site.
   */
  String systemCacheDirectory(PackageId id) {
    var parsed = _parseDescription(id.description);
    var url = parsed.last.replaceAll(new RegExp(r"^https?://"), "");
    var urlDir = replace(url, new RegExp(r'[<>:"\\/|?*%]'), (match) {
      return '%${match[0].charCodeAt(0)}';
    });
    return join(systemCacheRoot, urlDir, "${parsed.first}-${id.version}");
  }

  String packageName(description) => _parseDescription(description).first;

  bool descriptionsEqual(description1, description2) =>
      _parseDescription(description1) == _parseDescription(description2);

  /**
   * Ensures that [description] is a valid hosted package description.
   *
   * There are two valid formats. A plain string refers to a package with the
   * given name from the default host, while a map with keys "name" and "url"
   * refers to a package with the given name from the host at the given URL.
   */
  void validateDescription(description, {bool fromLockFile: false}) {
    _parseDescription(description);
  }

  /// When an error occurs trying to read something about [package] from [url],
  /// this tries to translate into a more user friendly error message. Always
  /// throws an error, either the original one or a better one.
  void _throwFriendlyError(ex, package, url) {
    if (ex is PubHttpException && ex.statusCode == 404) {
      throw 'Could not find package "$package" at $url.';
    }

    if (ex is TimeoutException) {
      throw 'Timed out trying to find package "$package" at $url.';
    }

    if (ex is io.SocketIOException) {
      throw 'Got socket error trying to find package "$package" at $url.\n'
          '${ex.osError}';
    }

    // Otherwise re-throw the original exception.
    throw ex;
  }

  /**
   * Parses the description for a package.
   *
   * If the package parses correctly, this returns a (name, url) pair. If not,
   * this throws a descriptive FormatException.
   */
  Pair<String, String> _parseDescription(description) {
    if (description is String) {
      return new Pair<String, String>(description, defaultUrl);
    }

    if (description is! Map) {
      throw new FormatException(
          "The description must be a package name or map.");
    }

    if (!description.containsKey("name")) {
      throw new FormatException(
          "The description map must contain a 'name' key.");
    }

    var name = description["name"];
    if (name is! String) {
      throw new FormatException("The 'name' key must have a string value.");
    }

    var url = description.containsKey("url") ? description["url"] : defaultUrl;
    return new Pair<String, String>(name, url);
  }
}
