// Copyright (c) 2016, 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:http/http.dart' as http;

import 'no_package_resolver.dart';
import 'package_config_resolver.dart';
import 'package_resolver.dart';
import 'package_root_resolver.dart';
import 'utils.dart';

/// A class that defines how to resolve `package:` URIs.
///
/// This includes the information necessary to resolve `package:` URIs using
/// either a package config or a package root. It can be used both as a standard
/// cross-package representation of the user's configuration, and as a means of
/// concretely locating packages and the assets they contain.
///
/// Unlike [PackageResolver], all members on this are synchronous, which may
/// require that more data be loaded up front. This is useful when primarily
/// dealing with user-created package resolution strategies, whereas
/// [PackageInfo] is usually preferable when the current Isolate's package
/// resolution logic may be used.
///
/// This class should not be implemented by user code.
abstract class SyncPackageResolver {
  /// The map contained in the parsed package config.
  ///
  /// This maps package names to the base URIs for those packages. These are
  /// already resolved relative to [packageConfigUri], so if they're relative
  /// they should be considered relative to [Uri.base]. They're normalized to
  /// ensure that all URLs end with a trailing slash.
  ///
  /// [urlFor] should generally be used rather than looking up package URLs in
  /// this map, to ensure that code works with a package root as well as a
  /// package config.
  ///
  /// Returns `null` when using a [packageRoot] for resolution, or when no
  /// package resolution is being used.
  Map<String, Uri> get packageConfigMap;

  /// The URI for the package config.
  ///
  /// This is the URI from which [packageConfigMap] was parsed, if that's
  /// available. Otherwise, it's a `data:` URI containing a serialized
  /// representation of [packageConfigMap]. This `data:` URI should be accepted
  /// by all Dart tools.
  ///
  /// Note that if this is a `data:` URI, it's likely not safe to pass as a
  /// parameter to a Dart process due to length limits.
  ///
  /// Returns `null` when using a [packageRoot] for resolution, or when no
  /// package resolution is being used.
  Uri get packageConfigUri;

  /// The base URL for resolving `package:` URLs.
  ///
  /// This is normalized so that it always ends with a trailing slash.
  ///
  /// Returns `null` when using a [packageConfigMap] for resolution, or when no
  /// package resolution is being used.
  Uri get packageRoot;

  /// Returns a wrapper for [this] that implements [PackageResolver].
  PackageResolver get asAsync;

  /// Returns the argument to pass to a subprocess to get it to use this package
  /// resolution strategy when resolving `package:` URIs.
  ///
  /// This uses the `--package-root` or `--package` flags, which are the
  /// convention supported by the Dart VM and dart2js.
  ///
  /// Note that if [packageConfigUri] is a `data:` URI, it may be too large to
  /// pass on the command line.
  ///
  /// Returns `null` if no package resolution is in use.
  String get processArgument;

  /// Returns a package resolution strategy describing how the current isolate
  /// resolves `package:` URIs.
  ///
  /// This may throw exceptions if loading or parsing the isolate's package map
  /// fails.
  static final Future<SyncPackageResolver> current =
      PackageResolver.current.asSync;

  /// Returns a package resolution strategy that is unable to resolve any
  /// `package:` URIs.
  static final SyncPackageResolver none = new NoPackageResolver();

  /// Loads a package config file from [uri] and returns its package resolution
  /// strategy.
  ///
  /// This supports `file:`, `http:`, `data:` and `package:` URIs. It throws an
  /// [UnsupportedError] for any other schemes. If [client] is passed and an
  /// HTTP request is needed, it's used to make that request; otherwise, a
  /// default client is used.
  ///
  /// [uri] may be a [String] or a [Uri].
  static Future<SyncPackageResolver> loadConfig(uri,
      {http.Client client}) async {
    uri = asUri(uri, "uri");
    return new SyncPackageResolver.config(
        await loadConfigMap(uri, client: client),
        uri: uri);
  }

  /// Returns the package resolution strategy for the given [packageConfigMap].
  ///
  /// If passed, [uri] specifies the URI from which [packageConfigMap] was
  /// loaded. It may be a [String] or a [Uri].
  ///
  /// Whether or not [uri] is passed, [packageConfigMap] is expected to be
  /// fully-resolved. That is, any relative URIs in the original package config
  /// source should be resolved relative to its location.
  factory SyncPackageResolver.config(Map<String, Uri> packageConfigMap, {uri}) =
      PackageConfigResolver;

  /// Returns the package resolution strategy for the given [packageRoot], which
  /// may be a [String] or a [Uri].
  factory SyncPackageResolver.root(packageRoot) = PackageRootResolver;

  /// Resolves [packageUri] according to this package resolution strategy.
  ///
  /// [packageUri] may be a [String] or a [Uri]. This throws a [FormatException]
  /// if [packageUri] isn't a `package:` URI or doesn't have at least one path
  /// segment.
  ///
  /// If [packageUri] refers to a package that's not in the package spec, this
  /// returns `null`.
  Uri resolveUri(packageUri);

  /// Returns the resolved URL for [package] and [path].
  ///
  /// This is equivalent to `resolveUri("package:$package/")` or
  /// `resolveUri("package:$package/$path")`, depending on whether [path] was
  /// passed.
  ///
  /// If [package] refers to a package that's not in the package spec, this
  /// returns `null`.
  Uri urlFor(String package, [String path]);

  /// Returns the `package:` URI for [url].
  ///
  /// If [url] can't be referred to using a `package:` URI, returns `null`.
  ///
  /// [url] may be a [String] or a [Uri].
  Uri packageUriFor(url);

  /// Returns the path on the local filesystem to the root of [package], or
  /// `null` if the root cannot be found.
  ///
  /// **Note**: this assumes a pub-style package layout. In particular:
  ///
  /// * If a package root is being used, this assumes that it contains symlinks
  ///   to packages' lib/ directories.
  ///
  /// * If a package config is being used, this assumes that each entry points
  ///   to a package's lib/ directory.
  ///
  /// If these assumptions are broken, this may return `null` or it may return
  /// an invalid result.
  ///
  /// Returns `null` if the package root is not a `file:` URI, or if the package
  /// config entry for [package] is not a `file:` URI.
  String packagePath(String package);
}
