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

import 'io.dart';
import 'package.dart';
import 'pubspec.dart';
import 'system_cache.dart';
import 'version.dart';

/// A source from which to install packages.
///
/// Each source has many packages that it looks up using [PackageId]s. The
/// source is responsible for installing these packages to the package cache.
abstract class Source {
  /// The name of the source. Should be lower-case, suitable for use in a
  /// filename, and unique accross all sources.
  String get name;

  /// Whether or not this source is the default source.
  bool get isDefault => systemCache.sources.defaultSource == this;

  /// Whether this source's packages should be cached in Pub's global cache
  /// directory.
  ///
  /// A source should be cached if it requires network access to retrieve
  /// packages. It doesn't need to be cached if all packages are available
  /// locally.
  bool get shouldCache;

  /// The system cache with which this source is registered.
  SystemCache get systemCache {
    assert(_systemCache != null);
    return _systemCache;
  }

  /// The system cache variable. Set by [_bind].
  SystemCache _systemCache;

  /// The root directory of this source's cache within the system cache.
  ///
  /// This shouldn't be overridden by subclasses.
  String get systemCacheRoot => join(systemCache.rootDir, name);

  /// Records the system cache to which this source belongs.
  ///
  /// This should only be called once for each source, by
  /// [SystemCache.register]. It should not be overridden by base classes.
  void bind(SystemCache systemCache) {
    assert(_systemCache == null);
    this._systemCache = systemCache;
  }

  /// Get the list of all versions that exist for the package described by
  /// [description]. [name] is the expected name of the package.
  ///
  /// Note that this does *not* require the packages to be installed, which is
  /// the point. This is used during version resolution to determine which
  /// package versions are available to be installed (or already installed).
  ///
  /// By default, this assumes that each description has a single version and
  /// uses [describe] to get that version.
  Future<List<Version>> getVersions(String name, description) {
    return describe(new PackageId(name, this, Version.none, description))
      .transform((pubspec) => [pubspec.version]);
  }

  /// Loads the (possibly remote) pubspec for the package version identified by
  /// [id]. This may be called for packages that have not yet been installed
  /// during the version resolution process.
  ///
  /// For cached sources, by default this uses [installToSystemCache] to get the
  /// pubspec. There is no default implementation for non-cached sources; they
  /// must implement it manually.
  Future<Pubspec> describe(PackageId id) {
    if (!shouldCache) throw "Source $name must implement describe(id).";
    return installToSystemCache(id).transform((package) => package.pubspec);
  }

  /// Installs the package identified by [id] to [path]. Returns a [Future] that
  /// completes when the installation was finished. The [Future] should resolve
  /// to true if the package was found in the source and false if it wasn't. For
  /// all other error conditions, it should complete with an exception.
  ///
  /// [path] is guaranteed not to exist, and its parent directory is guaranteed
  /// to exist.
  ///
  /// Note that [path] may be deleted. If re-installing a package that has
  /// already been installed would be costly or impossible,
  /// [installToSystemCache] should be implemented instead of [install].
  ///
  /// This doesn't need to be implemented if [installToSystemCache] is
  /// implemented.
  Future<bool> install(PackageId id, String path) {
    throw "Either install or installToSystemCache must be implemented for "
        "source $name.";
  }

  /// Installs the package identified by [id] to the system cache. This is only
  /// called for sources with [shouldCache] set to true.
  ///
  /// By default, this uses [systemCacheDirectory] and [install].
  Future<Package> installToSystemCache(PackageId id) {
    var path = systemCacheDirectory(id);
    return exists(path).chain((exists) {
      if (exists) return new Future<bool>.immediate(true);
      return ensureDir(dirname(path)).chain((_) => install(id, path));
    }).chain((found) {
      if (!found) throw 'Package $id not found.';
      return Package.load(id.name, path, systemCache.sources);
    });
  }

  /// Returns the directory in the system cache that the package identified by
  /// [id] should be installed to. This should return a path to a subdirectory
  /// of [systemCacheRoot].
  ///
  /// This doesn't need to be implemented if [shouldCache] is false, or if
  /// [installToSystemCache] is implemented.
  String systemCacheDirectory(PackageId id) {
    throw 'Source.systemCacheDirectory must be implemented if shouldCache is '
        'true and installToSystemCache is not implemented.';
  }

  /// When a [Pubspec] or [LockFile] is parsed, it reads in the description for
  /// each dependency. It is up to the dependency's [Source] to determine how
  /// that should be interpreted. This will be called during parsing to validate
  /// that the given [description] is well-formed according to this source. It
  /// should return if the description is valid, or throw a [FormatException] if
  /// not.
  ///
  /// [fromLockFile] is true when the description comes from a [LockFile], to
  /// allow the source to use lockfile-specific descriptions via [resolveId].
  void validateDescription(description, {bool fromLockFile: false}) {}

  /// Returns whether or not [description1] describes the same package as
  /// [description2] for this source. This method should be light-weight. It
  /// doesn't need to validate that either package exists.
  ///
  /// By default, just uses regular equality.
  bool descriptionsEqual(description1, description2) =>
    description1 == description2;

  /// For some sources, [PackageId]s can point to different chunks of code at
  /// different times. This takes such an [id] and returns a future that
  /// completes to a [PackageId] that will uniquely specify a single chunk of
  /// code forever.
  ///
  /// For example, [GitSource] might take an [id] with description
  /// `http://github.com/dart-lang/some-lib.git` and return an id with a
  /// description that includes the current commit of the Git repository.
  ///
  /// This will be called after the package identified by [id] is installed, so
  /// the source can use the installed package to determine information about
  /// the resolved id.
  ///
  /// The returned [PackageId] may have a description field that's invalid
  /// according to [validateDescription], although it must still be serializable
  /// to JSON and YAML. It must also be equal to [id] according to
  /// [descriptionsEqual].
  ///
  /// By default, this just returns [id].
  Future<PackageId> resolveId(PackageId id) => new Future.immediate(id);

  /// Returns the source's name.
  String toString() => name;
}
