// 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 package_config.packagemap;

class Packages {
  static const int _EQUALS = 0x3d;
  static const int _CR = 0x0d;
  static const int _NL = 0x0a;
  static const int _NUMBER_SIGN = 0x23;

  final Map<String, Uri> packageMapping;

  Packages(this.packageMapping);

  /// Resolves a URI to a non-package URI.
  ///
  /// If [uri] is a `package:` URI, the location is resolved wrt. the
  /// [packageMapping].
  /// Otherwise the original URI is returned.
  Uri resolve(Uri uri) {
    if (uri.scheme.toLowerCase() != "package") {
      return uri;
    }
    if (uri.hasAuthority) {
      throw new ArgumentError.value(uri, "uri", "Must not have authority");
    }
    if (uri.path.startsWith("/")) {
      throw new ArgumentError.value(
          uri, "uri", "Path must not start with '/'.");
    }
    // Normalizes the path by removing '.' and '..' segments.
    uri = uri.normalizePath();
    String path = uri.path;
    var slashIndex = path.indexOf('/');
    String packageName;
    String rest;
    if (slashIndex < 0) {
      packageName = path;
      rest = "";
    } else {
      packageName = path.substring(0, slashIndex);
      rest = path.substring(slashIndex + 1);
    }
    Uri packageLocation = packageMapping[packageName];
    if (packageLocation == null) {
      throw new ArgumentError.value(
          uri, "uri", "Unknown package name: $packageName");
    }
    return packageLocation.resolveUri(new Uri(path: rest));
  }

  /// Parses a `packages.cfg` file into a `Packages` object.
  ///
  /// The [baseLocation] is used as a base URI to resolve all relative
  /// URI references against.
  ///
  /// The `Packages` object allows resolving package: URIs and writing
  /// the mapping back to a file or string.
  /// The [packageMapping] will contain a simple mapping from package name
  /// to package location.
  static Packages parse(String source, Uri baseLocation) {
    int index = 0;
    Map<String, Uri> result = <String, Uri>{};
    while (index < source.length) {
      bool isComment = false;
      int start = index;
      int eqIndex = -1;
      int end = source.length;
      int char = source.codeUnitAt(index++);
      if (char == _CR || char == _NL) {
        continue;
      }
      if (char == _EQUALS) {
        throw new FormatException("Missing package name", source, index - 1);
      }
      isComment = char == _NUMBER_SIGN;
      while (index < source.length) {
        char = source.codeUnitAt(index++);
        if (char == _EQUALS && eqIndex < 0) {
          eqIndex = index - 1;
        } else if (char == _NL || char == _CR) {
          end = index - 1;
          break;
        }
      }
      if (isComment) continue;
      if (eqIndex < 0) {
        throw new FormatException("No '=' on line", source, index - 1);
      }
      _checkIdentifier(source, start, eqIndex);
      var packageName = source.substring(start, eqIndex);

      var packageLocation = Uri.parse(source, eqIndex + 1, end);
      if (!packageLocation.path.endsWith('/')) {
        packageLocation =
            packageLocation.replace(path: packageLocation.path + "/");
      }
      packageLocation = baseLocation.resolveUri(packageLocation);
      if (result.containsKey(packageName)) {
        throw new FormatException(
            "Same package name occured twice.", source, start);
      }
      result[packageName] = packageLocation;
    }
    return new Packages(result);
  }

  /**
   * Writes the mapping to a [StringSink].
   *
   * If [comment] is provided, the output will contain this comment
   * with `#` in front of each line.
   *
   * If [baseUri] is provided, package locations will be made relative
   * to the base URI, if possible, before writing.
   */
  void write(StringSink output, {Uri baseUri, String comment}) {
    if (baseUri != null && !baseUri.isAbsolute) {
      throw new ArgumentError.value(baseUri, "baseUri", "Must be absolute");
    }

    if (comment != null) {
      for (var commentLine in comment.split('\n')) {
        output.write('#');
        output.writeln(commentLine);
      }
    } else {
      output.write("# generated by package:packagecfg at ");
      output.write(new DateTime.now());
      output.writeln();
    }

    packageMapping.forEach((String packageName, Uri uri) {
      // Validate packageName.
      _checkIdentifier(packageName, 0, packageName.length);
      output.write(packageName);

      output.write('=');

      // If baseUri provided, make uri relative.
      if (baseUri != null) {
        uri = relativize(uri, baseUri);
      }
      output.write(uri);
      if (!uri.path.endsWith('/')) {
        output.write('/');
      }
      output.writeln();
    });
  }

  String toString() {
    StringBuffer buffer = new StringBuffer();
    write(buffer);
    return buffer.toString();
  }

  static Uri relativize(Uri uri, Uri baseUri) {
    if (uri.hasQuery || uri.hasFragment) {
      uri = new Uri(
          scheme: uri.scheme,
          userInfo: uri.hasAuthority ? uri.userInfo : null,
          host: uri.hasAuthority ? uri.host : null,
          port: uri.hasAuthority ? uri.port : null,
          path: uri.path);
    }
    if (!baseUri.isAbsolute) {
      throw new ArgumentError("Base uri '$baseUri' must be absolute.");
    }
    // Already relative.
    if (!uri.isAbsolute) return uri;

    if (baseUri.scheme.toLowerCase() != uri.scheme.toLowerCase()) {
      return uri;
    }
    // If authority differs, we could remove the scheme, but it's not worth it.
    if (uri.hasAuthority != baseUri.hasAuthority) return uri;
    if (uri.hasAuthority) {
      if (uri.userInfo != baseUri.userInfo ||
          uri.host.toLowerCase() != baseUri.host.toLowerCase() ||
          uri.port != baseUri.port) {
        return uri;
      }
    }

    baseUri = baseUri.normalizePath();
    List<String> base = baseUri.pathSegments.toList();
    if (base.isNotEmpty) {
      base = new List<String>.from(base)..removeLast();
    }
    uri = uri.normalizePath();
    List<String> target = uri.pathSegments.toList();
    int index = 0;
    while (index < base.length && index < target.length) {
      if (base[index] != target[index]) {
        break;
      }
      index++;
    }
    if (index == base.length) {
      return new Uri(path: target.skip(index).join('/'));
    } else if (index > 0) {
      return new Uri(
          path: '../' * (base.length - index) + target.skip(index).join('/'));
    } else {
      return uri;
    }
  }

  static bool _checkIdentifier(String string, int start, int end) {
    const int a = 0x61;
    const int z = 0x7a;
    const int _ = 0x5f;
    const int $ = 0x24;
    if (start == end) return false;
    for (int i = start; i < end; i++) {
      var char = string.codeUnitAt(i);
      if (char == _ || char == $) continue;
      if ((char ^ 0x30) <= 9 && i > 0) continue;
      char |= 0x20; // Lower-case letters.
      if (char >= a && char <= z) continue;
      throw new FormatException("Not an identifier", string, i);
    }
    return true;
  }
}
