// 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 'dart:collection';

import 'package:collection/collection.dart';
import 'package:package_config/packages_file.dart' as packages_file;
import 'package:path/path.dart' as p;

import 'async_package_resolver.dart';
import 'package_resolver.dart';
import 'sync_package_resolver.dart';
import 'utils.dart';

/// A package resolution strategy based on a package config map.
class PackageConfigResolver implements SyncPackageResolver {
  final packageRoot = null;

  final Map<String, Uri> packageConfigMap;

  Uri get packageConfigUri {
    if (_uri != null) return _uri;

    var buffer = StringBuffer();
    packages_file.write(buffer, packageConfigMap, comment: "");
    _uri =
        UriData.fromString(buffer.toString(), parameters: {"charset": "utf-8"})
            .uri;
    return _uri;
  }

  Uri _uri;

  PackageResolver get asAsync => AsyncPackageResolver(this);

  String get processArgument => "--packages=$packageConfigUri";

  PackageConfigResolver(Map<String, Uri> packageConfigMap, {uri})
      : packageConfigMap = _normalizeMap(packageConfigMap),
        _uri = uri == null ? null : asUri(uri, "uri");

  /// Normalizes the URIs in [map] to ensure that they all end in a trailing
  /// slash.
  static Map<String, Uri> _normalizeMap(Map<String, Uri> map) =>
      UnmodifiableMapView(
          mapMap(map, value: (_, uri) => ensureTrailingSlash(uri)));

  Uri resolveUri(packageUri) {
    var uri = asPackageUri(packageUri, "packageUri");

    var baseUri = packageConfigMap[uri.pathSegments.first];
    if (baseUri == null) return null;

    var segments = baseUri.pathSegments.toList()
      ..removeLast(); // Remove the trailing slash.

    // Following [Isolate.resolvePackageUri], "package:foo" resolves to null.
    if (uri.pathSegments.length == 1) return null;

    segments.addAll(uri.pathSegments.skip(1));
    return baseUri.replace(pathSegments: segments);
  }

  Uri urlFor(String package, [String path]) {
    var baseUri = packageConfigMap[package];
    if (baseUri == null) return null;
    if (path == null) return baseUri;
    return baseUri.resolve(path);
  }

  Uri packageUriFor(url) {
    url = asUri(url, "url").toString();

    // Make sure isWithin works if [url] is exactly the base.
    var nested = p.url.join(url, "_");
    for (var package in packageConfigMap.keys) {
      var base = packageConfigMap[package].toString();
      if (!p.url.isWithin(base, nested)) continue;

      var relative = p.url.relative(url, from: base);
      if (relative == '.') relative = '';
      return Uri.parse("package:$package/$relative");
    }

    return null;
  }

  String packagePath(String package) {
    var lib = packageConfigMap[package];
    if (lib == null) return null;
    if (lib.scheme != 'file') return null;
    return p.dirname(p.fromUri(lib));
  }
}
