// Copyright (c) 2019, 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:typed_data';

import 'errors.dart';
import "package_config_impl.dart";
import 'package_config_json.dart';

/// A package configuration.
///
/// Associates configuration data to packages and files in packages.
///
/// More members may be added to this class in the future,
/// so classes outside of this package must not implement [PackageConfig]
/// or any subclass of it.
abstract class PackageConfig {
  /// The largest configuration version currently recognized.
  static const int maxVersion = 2;

  /// An empty package configuration.
  ///
  /// A package configuration with no available packages.
  /// Is used as a default value where a package configuration
  /// is expected, but none have been specified or found.
  static const PackageConfig empty = SimplePackageConfig.empty();

  /// Creats a package configuration with the provided available [packages].
  ///
  /// The packages must be valid packages (valid package name, valid
  /// absolute directory URIs, valid language version, if any),
  /// and there must not be two packages with the same name.
  ///
  /// The package's root ([Package.rootUri]) and package-root
  /// ([Package.packageUriRoot]) paths must satisfy a number of constraints
  /// We say that one path (which we know ends with a `/` charater)
  /// is inside another path, if the latter path is a prefix of the former path,
  /// including the two paths being the same.
  ///
  /// * No package's root must be the same as another package's root.
  /// * The package-root of a package must be inside the pacakge's root.
  /// * If one package's package-root is inside another package's root,
  ///   then the latter package's package root must not be inside the former
  ///   package's root. (No getting between a package and its package root!)
  ///   This also disallows a package's root being the same as another
  ///   package's package root.
  ///
  /// If supplied, the [extraData] will be available as the
  /// [PackageConfig.extraData] of the created configuration.
  ///
  /// The version of the resulting configuration is always [maxVersion].
  factory PackageConfig(Iterable<Package> packages, {dynamic extraData}) =>
      SimplePackageConfig(maxVersion, packages, extraData);

  /// Parses a package configuration file.
  ///
  /// The [bytes] must be an UTF-8 encoded JSON object
  /// containing a valid package configuration.
  ///
  /// The [baseUri] is used as the base for resolving relative
  /// URI references in the configuration file. If the configuration
  /// has been read from a file, the [baseUri] can be the URI of that
  /// file, or of the directory it occurs in.
  ///
  /// If [onError] is provided, errors found during parsing or building
  /// the configuration are reported by calling [onError] instead of
  /// throwing, and parser makes a *best effort* attempt to continue
  /// despite the error. The input must still be valid JSON.
  /// The result may be a [PackageConfig.empty] if there is no way to
  /// extract useful information from the bytes.
  static PackageConfig parseBytes(Uint8List bytes, Uri baseUri,
          {void onError(Object error)}) =>
      parsePackageConfigBytes(bytes, baseUri, onError ?? throwError);

  /// Parses a package configuration file.
  ///
  /// The [configuration] must be a JSON object
  /// containing a valid package configuration.
  ///
  /// The [baseUri] is used as the base for resolving relative
  /// URI references in the configuration file. If the configuration
  /// has been read from a file, the [baseUri] can be the URI of that
  /// file, or of the directory it occurs in.
  ///
  /// If [onError] is provided, errors found during parsing or building
  /// the configuration are reported by calling [onError] instead of
  /// throwing, and parser makes a *best effort* attempt to continue
  /// despite the error. The input must still be valid JSON.
  /// The result may be a [PackageConfig.empty] if there is no way to
  /// extract useful information from the bytes.
  static PackageConfig parseString(String configuration, Uri baseUri,
          {void onError(Object error)}) =>
      parsePackageConfigString(configuration, baseUri, onError ?? throwError);

  /// Parses the JSON data of a package configuration file.
  ///
  /// The [configuration] must be a JSON-like Dart data structure,
  /// like the one provided by parsing JSON text using `dart:convert`,
  /// containing a valid package configuration.
  ///
  /// The [baseUri] is used as the base for resolving relative
  /// URI references in the configuration file. If the configuration
  /// has been read from a file, the [baseUri] can be the URI of that
  /// file, or of the directory it occurs in.
  ///
  /// If [onError] is provided, errors found during parsing or building
  /// the configuration are reported by calling [onError] instead of
  /// throwing, and parser makes a *best effort* attempt to continue
  /// despite the error. The input must still be valid JSON.
  /// The result may be a [PackageConfig.empty] if there is no way to
  /// extract useful information from the bytes.
  static PackageConfig parseJson(dynamic jsonData, Uri baseUri,
          {void onError(Object error)}) =>
      parsePackageConfigJson(jsonData, baseUri, onError ?? throwError);

  /// Writes a configuration file for this configuration on [output].
  ///
  /// If [baseUri] is provided, URI references in the generated file
  /// will be made relative to [baseUri] where possible.
  static void writeBytes(PackageConfig configuration, Sink<Uint8List> output,
      [Uri /*?*/ baseUri]) {
    writePackageConfigJsonUtf8(configuration, baseUri, output);
  }

  /// Writes a configuration JSON text for this configuration on [output].
  ///
  /// If [baseUri] is provided, URI references in the generated file
  /// will be made relative to [baseUri] where possible.
  static void writeString(PackageConfig configuration, StringSink output,
      [Uri /*?*/ baseUri]) {
    writePackageConfigJsonString(configuration, baseUri, output);
  }

  /// Converts a configuration to a JSON-like data structure.
  ///
  /// If [baseUri] is provided, URI references in the generated data
  /// will be made relative to [baseUri] where possible.
  static Map<String, dynamic> toJson(PackageConfig configuration,
          [Uri /*?*/ baseUri]) =>
      packageConfigToJson(configuration, baseUri);

  /// The configuration version number.
  ///
  /// Currently this is 1 or 2, where
  /// * Version one is the `.packages` file format and
  /// * Version two is the first `package_config.json` format.
  ///
  /// Instances of this class supports both, and the version
  /// is only useful for detecting which kind of file the configuration
  /// was read from.
  int get version;

  /// All the available packages of this configuration.
  ///
  /// No two of these packages have the same name,
  /// and no two [Package.root] directories overlap.
  Iterable<Package> get packages;

  /// Look up a package by name.
  ///
  /// Returns the [Package] fron [packages] with [packageName] as
  /// [Package.name]. Returns `null` if the package is not available in the
  /// current configuration.
  Package /*?*/ operator [](String packageName);

  /// Provides the associated package for a specific [file] (or directory).
  ///
  /// Returns a [Package] which contains the [file]'s path, if any.
  /// That is, the [Package.rootUri] directory is a parent directory
  /// of the [file]'s location.
  ///
  /// Returns `null` if the file does not belong to any package.
  Package /*?*/ packageOf(Uri file);

  /// Resolves a `package:` URI to a non-package URI
  ///
  /// The [packageUri] must be a valid package URI. That means:
  /// * A URI with `package` as scheme,
  /// * with no authority part (`package://...`),
  /// * with a path starting with a valid package name followed by a slash, and
  /// * with no query or fragment part.
  ///
  /// Throws an [ArgumentError] (which also implements [PackageConfigError])
  /// if the package URI is not valid.
  ///
  /// Returns `null` if the package name of [packageUri] is not available
  /// in this package configuration.
  /// Returns the remaining path of the package URI resolved relative to the
  /// [Package.packageUriRoot] of the corresponding package.
  Uri /*?*/ resolve(Uri packageUri);

  /// The package URI which resolves to [nonPackageUri].
  ///
  /// The [nonPackageUri] must not have any query or fragment part,
  /// and it must not have `package` as scheme.
  /// Throws an [ArgumentError] (which also implements [PackageConfigError])
  /// if the non-package URI is not valid.
  ///
  /// Returns a package URI which [resolve] will convert to [nonPackageUri],
  /// if any such URI exists. Returns `null` if no such package URI exists.
  Uri /*?*/ toPackageUri(Uri nonPackageUri);

  /// Extra data associated with the package configuration.
  ///
  /// The data may be in any format, depending on who introduced it.
  /// The standard `packjage_config.json` file storage will only store
  /// JSON-like list/map data structures.
  dynamic get extraData;
}

/// Configuration data for a single package.
abstract class Package {
  /// Creates a package with the provided properties.
  ///
  /// The [name] must be a valid package name.
  /// The [root] must be an absolute directory URI, meaning an absolute URI
  /// with no query or fragment path and a path starting and ending with `/`.
  /// The [packageUriRoot], if provided, must be either an absolute
  /// directory URI or a relative URI reference which is then resolved
  /// relative to [root]. It must then also be a subdirectory of [root],
  /// or the same directory, and must end with `/`.
  /// If [languageVersion] is supplied, it must be a valid Dart language
  /// version, which means two decimal integer literals separated by a `.`,
  /// where the integer literals have no leading zeros unless they are
  /// a single zero digit.
  /// If [extraData] is supplied, it will be available as the
  /// [Package.extraData] of the created package.
  factory Package(String name, Uri root,
          {Uri /*?*/ packageUriRoot,
          LanguageVersion /*?*/ languageVersion,
          dynamic extraData}) =>
      SimplePackage.validate(
          name, root, packageUriRoot, languageVersion, extraData, throwError);

  /// The package-name of the package.
  String get name;

  /// The location of the root of the package.
  ///
  /// Is always an absolute URI with no query or fragment parts,
  /// and with a path ending in `/`.
  ///
  /// All files in the [rootUri] directory are considered
  /// part of the package for purposes where that that matters.
  Uri get root;

  /// The root of the files available through `package:` URIs.
  ///
  /// A `package:` URI with [name] as the package name is
  /// resolved relative to this location.
  ///
  /// Is always an absolute URI with no query or fragment part
  /// with a path ending in `/`,
  /// and with a location which is a subdirectory
  /// of the [root], or the same as the [root].
  Uri get packageUriRoot;

  /// The default language version associated with this package.
  ///
  /// Each package may have a default language version associated,
  /// which is the language version used to parse and compile
  /// Dart files in the package.
  /// A package version is defined by two non-negative numbers,
  /// the *major* and *minor* version numbers.
  LanguageVersion /*?*/ get languageVersion;

  /// Extra data associated with the specific package.
  ///
  /// The data may be in any format, depending on who introduced it.
  /// The standard `packjage_config.json` file storage will only store
  /// JSON-like list/map data structures.
  dynamic get extraData;
}

/// A language version.
///
/// A language version is represented by two non-negative integers,
/// the [major] and [minor] version numbers.
///
/// If errors during parsing are handled using an `onError` handler,
/// then an *invalid* language version may be represented by an
/// [InvalidLanguageVersion] object.
abstract class LanguageVersion implements Comparable<LanguageVersion> {
  /// The maximal value allowed by [major] and [minor] values;
  static const int maxValue = 0x7FFFFFFF;
  factory LanguageVersion(int major, int minor) {
    RangeError.checkValueInInterval(major, 0, maxValue, "major");
    RangeError.checkValueInInterval(minor, 0, maxValue, "major");
    return SimpleLanguageVersion(major, minor, null);
  }

  /// Parses a language version string.
  ///
  /// A valid language version string has the form
  ///
  /// > *decimalNumber* `.` *decimalNumber*
  ///
  /// where a *decimalNumber* is a non-empty sequence of decimal digits
  /// with no unnecessary leading zeros (the decimal number only starts
  /// with a zero digit if that digit is the entire number).
  /// No spaces are allowed in the string.
  ///
  /// If the [source] is valid then it is parsed into a valid
  /// [LanguageVersion] object.
  /// If not, then the [onError] is called with a [FormatException].
  /// If [onError] is not supplied, it defaults to throwing the exception.
  /// If the call does not throw, then an [InvalidLanguageVersion] is returned
  /// containing the original [source].
  static LanguageVersion parse(String source, {void onError(Object error)}) =>
      parseLanguageVersion(source, onError ?? throwError);

  /// The major language version.
  ///
  /// A non-negative integer less than 2<sup>31</sup>.
  ///
  /// The value is negative for objects representing *invalid* language
  /// versions ([InvalidLanguageVersion]).
  int get major;

  /// The minor language version.
  ///
  /// A non-negative integer less than 2<sup>31</sup>.
  ///
  /// The value is negative for objects representing *invalid* language
  /// versions ([InvalidLanguageVersion]).
  int get minor;

  /// Compares language versions.
  ///
  /// Two language versions are considered equal if they have the
  /// same major and minor version numbers.
  ///
  /// A language version is greater then another if the former's major version
  /// is greater than the latter's major version, or if they have
  /// the same major version and the former's minor version is greater than
  /// the latter's.
  int compareTo(LanguageVersion other);

  /// Valid language versions with the same [major] and [minor] values are
  /// equal.
  ///
  /// Invalid language versions ([InvalidLanguageVersion]) are not equal to
  /// any other object.
  bool operator ==(Object other);

  int get hashCode;

  /// A string representation of the language version.
  ///
  /// A valid language version is represented as
  /// `"${version.major}.${version.minor}"`.
  String toString();
}

/// An *invalid* language version.
///
/// Stored in a [Package] when the orginal language version string
/// was invalid and a `onError` handler was passed to the parser
/// which did not throw on an error.
abstract class InvalidLanguageVersion implements LanguageVersion {
  /// The value -1 for an invalid language version.
  int get major;

  /// The value -1 for an invalid language version.
  int get minor;

  /// An invalid language version is only equal to itself.
  bool operator ==(Object other);

  int get hashCode;

  /// The original invalid version string.
  String toString();
}
