// 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.

// @dart = 2.5

library libraries;

/**
 * A bit flag used by [LibraryInfo] indicating that a library is used by dart2js
 */
const int DART2JS_PLATFORM = 1;

/**
 * A bit flag used by [LibraryInfo] indicating that a library is used by the VM
 */
const int VM_PLATFORM = 2;

/// The contexts that a library can be used from.
enum Category {
  /// Indicates that a library can be used in a browser context.
  client,

  /// Indicates that a library can be used in a command line context.
  server,

  /// Indicates that a library can be used from embedded devices.
  embedded
}

Category parseCategory(String name) {
  switch (name) {
    case "Client":
      return Category.client;
    case "Server":
      return Category.server;
    case "Embedded":
      return Category.embedded;
  }
  return null;
}

/// Mapping of "dart:" library name (e.g. "core") to information about that
/// library.
const Map<String, LibraryInfo> libraries = const {
  "async": const LibraryInfo("async/async.dart",
      categories: "Client,Server",
      maturity: Maturity.STABLE,
      dart2jsPatchPath: "_internal/js_runtime/lib/async_patch.dart"),
  "collection": const LibraryInfo("collection/collection.dart",
      categories: "Client,Server,Embedded",
      maturity: Maturity.STABLE,
      dart2jsPatchPath: "_internal/js_runtime/lib/collection_patch.dart"),
  "convert": const LibraryInfo("convert/convert.dart",
      categories: "Client,Server",
      maturity: Maturity.STABLE,
      dart2jsPatchPath: "_internal/js_runtime/lib/convert_patch.dart"),
  "core": const LibraryInfo("core/core.dart",
      categories: "Client,Server,Embedded",
      maturity: Maturity.STABLE,
      dart2jsPatchPath: "_internal/js_runtime/lib/core_patch.dart"),
  "developer": const LibraryInfo("developer/developer.dart",
      categories: "Client,Server,Embedded",
      maturity: Maturity.UNSTABLE,
      dart2jsPatchPath: "_internal/js_runtime/lib/developer_patch.dart"),
  "ffi": const LibraryInfo("ffi/ffi.dart",
      categories: "Server",
      // TODO(dacoharkes): Update maturity when we release dart:ffi.
      // https://github.com/dart-lang/sdk/issues/34452
      maturity: Maturity.EXPERIMENTAL),
  "html": const LibraryInfo("html/dart2js/html_dart2js.dart",
      categories: "Client",
      maturity: Maturity.WEB_STABLE,
      platforms: DART2JS_PLATFORM),
  "html_common": const LibraryInfo("html/html_common/html_common.dart",
      categories: "Client",
      maturity: Maturity.WEB_STABLE,
      dart2jsPath: "html/html_common/html_common_dart2js.dart",
      documented: false,
      implementation: true),
  "indexed_db": const LibraryInfo("indexed_db/dart2js/indexed_db_dart2js.dart",
      categories: "Client",
      maturity: Maturity.WEB_STABLE,
      platforms: DART2JS_PLATFORM),
  "_http":
      const LibraryInfo("_http/http.dart", categories: "", documented: false),
  "io": const LibraryInfo("io/io.dart",
      categories: "Server",
      dart2jsPatchPath: "_internal/js_runtime/lib/io_patch.dart"),
  "isolate": const LibraryInfo("isolate/isolate.dart",
      categories: "Client,Server",
      maturity: Maturity.STABLE,
      dart2jsPatchPath: "_internal/js_runtime/lib/isolate_patch.dart"),
  "js": const LibraryInfo("js/js.dart",
      categories: "Client",
      maturity: Maturity.STABLE,
      platforms: DART2JS_PLATFORM,
      dart2jsPatchPath: "_internal/js_runtime/lib/js_patch.dart"),
  "_js": const LibraryInfo("js/_js.dart",
      categories: "Client",
      dart2jsPatchPath: "js/_js_client.dart",
      documented: false,
      platforms: DART2JS_PLATFORM),
  "js_util": const LibraryInfo("js_util/js_util.dart",
      categories: "Client",
      maturity: Maturity.STABLE,
      platforms: DART2JS_PLATFORM),
  "math": const LibraryInfo("math/math.dart",
      categories: "Client,Server,Embedded",
      maturity: Maturity.STABLE,
      dart2jsPatchPath: "_internal/js_runtime/lib/math_patch.dart"),
  "mirrors": const LibraryInfo("mirrors/mirrors.dart",
      categories: "Client,Server",
      maturity: Maturity.UNSTABLE,
      dart2jsPatchPath: "_internal/js_runtime/lib/mirrors_patch_cfe.dart"),
  "nativewrappers": const LibraryInfo("html/dartium/nativewrappers.dart",
      categories: "Client",
      implementation: true,
      documented: false,
      platforms: VM_PLATFORM),
  "typed_data": const LibraryInfo("typed_data/typed_data.dart",
      categories: "Client,Server,Embedded",
      maturity: Maturity.STABLE,
      dart2jsPatchPath: "_internal/js_runtime/lib/typed_data_patch.dart"),
  "_native_typed_data": const LibraryInfo(
      "_internal/js_runtime/lib/native_typed_data.dart",
      categories: "",
      implementation: true,
      documented: false,
      platforms: DART2JS_PLATFORM),
  "cli": const LibraryInfo("cli/cli.dart",
      categories: "Server", platforms: VM_PLATFORM),
  "svg": const LibraryInfo("svg/dart2js/svg_dart2js.dart",
      categories: "Client",
      maturity: Maturity.WEB_STABLE,
      platforms: DART2JS_PLATFORM),
  "web_audio": const LibraryInfo("web_audio/dart2js/web_audio_dart2js.dart",
      categories: "Client",
      maturity: Maturity.WEB_STABLE,
      platforms: DART2JS_PLATFORM),
  "web_gl": const LibraryInfo("web_gl/dart2js/web_gl_dart2js.dart",
      categories: "Client",
      maturity: Maturity.WEB_STABLE,
      platforms: DART2JS_PLATFORM),
  "web_sql": const LibraryInfo("web_sql/dart2js/web_sql_dart2js.dart",
      categories: "Client",
      maturity: Maturity.WEB_STABLE,
      platforms: DART2JS_PLATFORM),
  "_internal": const LibraryInfo("internal/internal.dart",
      categories: "",
      documented: false,
      dart2jsPatchPath: "_internal/js_runtime/lib/internal_patch.dart"),
  "_js_helper": const LibraryInfo("_internal/js_runtime/lib/js_helper.dart",
      categories: "", documented: false, platforms: DART2JS_PLATFORM),
  "_rti": const LibraryInfo("_internal/js_runtime/lib/rti.dart",
      categories: "", documented: false, platforms: DART2JS_PLATFORM),
  "_interceptors": const LibraryInfo(
      "_internal/js_runtime/lib/interceptors.dart",
      categories: "",
      documented: false,
      platforms: DART2JS_PLATFORM),
  "_foreign_helper": const LibraryInfo(
      "_internal/js_runtime/lib/foreign_helper.dart",
      categories: "",
      documented: false,
      platforms: DART2JS_PLATFORM),
  "_js_names": const LibraryInfo("_internal/js_runtime/lib/js_names.dart",
      categories: "", documented: false, platforms: DART2JS_PLATFORM),
  "_js_primitives": const LibraryInfo(
      "_internal/js_runtime/lib/js_primitives.dart",
      categories: "",
      documented: false,
      platforms: DART2JS_PLATFORM),
  "_js_embedded_names": const LibraryInfo(
      "_internal/js_runtime/lib/shared/embedded_names.dart",
      categories: "",
      documented: false,
      platforms: DART2JS_PLATFORM),
  "_async_await_error_codes": const LibraryInfo(
      "_internal/js_runtime/lib/shared/async_await_error_codes.dart",
      categories: "",
      documented: false,
      platforms: DART2JS_PLATFORM),
  "_recipe_syntax": const LibraryInfo(
      "_internal/js_runtime/lib/shared/recipe_syntax.dart",
      categories: "",
      documented: false,
      platforms: DART2JS_PLATFORM),
  "_metadata": const LibraryInfo("html/html_common/metadata.dart",
      categories: "", documented: false, platforms: DART2JS_PLATFORM),
  "_js_annotations": const LibraryInfo("js/_js_annotations.dart",
      categories: "", documented: false, platforms: DART2JS_PLATFORM),
};

/**
 * Information about a "dart:" library.
 */
class LibraryInfo {
  /**
   * Path to the library's *.dart file relative to this file.
   */
  final String path;

  /**
   * The categories in which the library can be used encoded as a
   * comma-separated String.
   */
  final String _categories;

  /**
   * Path to the dart2js library's *.dart file relative to this file
   * or null if dart2js uses the common library path defined above.
   * Access using the [#getDart2JsPath()] method.
   */
  final String dart2jsPath;

  /**
   * Path to the dart2js library's patch file relative to this file
   * or null if no dart2js patch file associated with this library.
   * Access using the [#getDart2JsPatchPath()] method.
   */
  final String dart2jsPatchPath;

  /**
   * True if this library is documented and should be shown to the user.
   */
  final bool documented;

  /**
   * Bit flags indicating which platforms consume this library.
   * See [DART2JS_LIBRARY] and [VM_LIBRARY].
   */
  final int platforms;

  /**
   * True if the library contains implementation details for another library.
   * The implication is that these libraries are less commonly used
   * and that tools like Dart Editor should not show these libraries
   * in a list of all libraries unless the user specifically asks the tool to
   * do so.
   */
  final bool implementation;

  /**
   * States the current maturity of this library.
   */
  final Maturity maturity;

  const LibraryInfo(this.path,
      {String categories: "",
      this.dart2jsPath,
      this.dart2jsPatchPath,
      this.implementation: false,
      this.documented: true,
      this.maturity: Maturity.UNSPECIFIED,
      this.platforms: DART2JS_PLATFORM | VM_PLATFORM})
      : _categories = categories;

  bool get isDart2jsLibrary => (platforms & DART2JS_PLATFORM) != 0;
  bool get isVmLibrary => (platforms & VM_PLATFORM) != 0;

  /**
   * The categories in which the library can be used.
   *
   * If no categories are specified, the library is internal and can not be
   * loaded by user code.
   */
  List<Category> get categories {
    // `"".split(,)` returns [""] not [], so we handle that case separately.
    if (_categories == "") return const <Category>[];
    return _categories.split(",").map(parseCategory).toList();
  }

  bool get isInternal => categories.isEmpty;

  /// The original "categories" String that was passed to the constructor.
  ///
  /// Can be used to construct a slightly modified copy of this LibraryInfo.
  String get categoriesString {
    return _categories;
  }
}

/**
 * Abstraction to capture the maturity of a library.
 */
class Maturity {
  final int level;
  final String name;
  final String description;

  const Maturity(this.level, this.name, this.description);

  String toString() => "$name: $level\n$description\n";

  static const Maturity DEPRECATED = const Maturity(0, "Deprecated",
      "This library will be remove before next major release.");

  static const Maturity EXPERIMENTAL = const Maturity(
      1,
      "Experimental",
      "This library is experimental and will likely change or be removed\n"
          "in future versions.");

  static const Maturity UNSTABLE = const Maturity(
      2,
      "Unstable",
      "This library is in still changing and have not yet endured\n"
          "sufficient real-world testing.\n"
          "Backwards-compatibility is NOT guaranteed.");

  static const Maturity WEB_STABLE = const Maturity(
      3,
      "Web Stable",
      "This library is tracking the DOM evolution as defined by WC3.\n"
          "Backwards-compatibility is NOT guaranteed.");

  static const Maturity STABLE = const Maturity(
      4,
      "Stable",
      "The library is stable. API backwards-compatibility is guaranteed.\n"
          "However implementation details might change.");

  static const Maturity LOCKED = const Maturity(5, "Locked",
      "This library will not change except when serious bugs are encountered.");

  static const Maturity UNSPECIFIED = const Maturity(-1, "Unspecified",
      "The maturity for this library has not been specified.");
}
