// Copyright (c) 2017, 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 specification in-memory representation.
///
/// Many dart tools are configurable to support different target platforms.  For
/// a given target, they need to know what libraries are available and where are
/// the sources and target-specific patches.
///
/// Here we define APIs to represent this specification and implement
/// serialization to (and deserialization from) a JSON file.
///
/// Here is an example specification JSON file:
///
///     {
///       "vm": {
///         "libraries": {
///             "core": {
///                "uri": "async/core.dart",
///                "patches": [
///                    "path/to/core_patch.dart",
///                    "path/to/list_patch.dart"
///                ]
///             }
///             "async": {
///                "uri": "async/async.dart",
///                "patches": "path/to/async_patch.dart"
///             }
///             "convert": {
///                "uri": "convert/convert.dart",
///             }
///             "mirrors": {
///                "uri": "mirrors/mirrors.dart",
///                "supported": false
///             }
///         }
///       }
///     }
///
/// The format contains:
///   - a top level entry for each target. Keys are target names (e.g. "vm"
///     above), and values contain the entire specification of a target.
///
///   - each target specification is a map. The supported keys are "libraries"
///     and "include".
///
///   - The "libraries" entry contains details for how each platform library is
///     implemented. The entry is a map, where keys are the name of the platform
///     library and values contain details for where to find the implementation
///     fo that library.
///
///   - The name of the library is a single token (e.g. "core") that matches the
///     Uri path used after `dart:` (e.g. "dart:core").
///
///   - The "uri" entry on the library information is mandatory. The value is a
///     string URI reference. The "patches" entry is optional and may have as a
///     value a string URI reference or a list of URI references.
///
///     All URI references can either be a file URI or a relative URI path,
///     which will be resolved relative to the location of the library
///     specification file.
///
///   - The "supported" entry on the library information is optional. The value
///     is a boolean indicating whether the library is supported in the
///     underlying target.  However, since the libraries are assumed to be
///     supported by default, we only expect users to use `false`.
///
///     The purpose of this value is to configure conditional imports and
///     environment constants. By default every platform library that is
///     available in the "libraries" section implicitly defines an environment
///     variable `dart.library.name` as `"true"`, to indicate that the library
///     is supported.  Some backends allow imports to an unsupported platform
///     library (turning a static error into a runtime error when the library is
///     eventually accessed). These backends can use `supported: false` to
///     report that such library is still not supported in conditional imports
///     and const `fromEnvironment` expressions.
///
///     Internal libraries are never supported through conditional imports and
///     const `fromEnvironment` expressions.
///
///   - The "include" entry is a list of maps, each containing either a "path"
///     and a "target" entry, or only a "target" entry.
///
///     If both "path" and "target" entries are present, the libraries
///     specification file located at "path", relative to the location current
///     libraries specification file is loaded, and the libraries defined
///     in the target with the target name of the "target" entry are included in
///     this target.
///
///     If only the "target" is present, the libraries in the target in the
///     current libraries specification file with the target name of the
///     "target" entry are included in this target.
///
///     The "include" mechanism support transitive inclusion but doesn't allow
///     cyclic dependencies.
///
///     If the same library is defined in multiple included target
///     specifications, the last included takes precedence. This means that
///     if a target specification include a library and also defines it itself,
///     the latter is used.
///
///     Currently it is not supported to include a subset of the libraries from
///     an included target specifications.
///
///
/// Note: we currently have several different files that need to be updated
/// when changing libraries, sources, and patch files:
///    * .platform files (for dart2js)
///    * .gypi files (for vm)
///    * sdk_library_metadata/lib/libraries.dart (for analyzer, ddc)
///
/// we are in the process of unifying them all under this format (see
/// https://github.com/dart-lang/sdk/issues/28836), but for now we need to pay
/// close attention to change them consistently.

import 'dart:convert' show jsonDecode, jsonEncode;

import 'relativize.dart' show relativizeUri, isWindows;

/// Contents from a single library specification file.
///
/// Contains information about all libraries on all target platforms defined in
/// that file.
class LibrariesSpecification {
  final Uri specUri;
  final Map<String, TargetLibrariesSpecification> _targets;

  const LibrariesSpecification(this.specUri,
      [this._targets = const <String, TargetLibrariesSpecification>{}]);

  /// The library specification for a given [target], or throws if none is
  /// available.
  TargetLibrariesSpecification specificationFor(String target) {
    TargetLibrariesSpecification? targetSpec = _targets[target];
    if (targetSpec == null) {
      throw new LibrariesSpecificationException(
          messageMissingTarget(target, specUri));
    }
    return targetSpec;
  }

  static Future<LibrariesSpecification> load(
      Uri uri, Future<String> Function(Uri uri) read) {
    Map<Uri, LibrariesSpecification?> cache = {};
    Future<LibrariesSpecification> loadSpecification(Uri uri) async {
      if (cache.containsKey(uri)) {
        LibrariesSpecification? specification = cache[uri];
        if (specification == null) {
          throw new LibrariesSpecificationException(messageCyclicSpec(uri));
        }
        return specification;
      }
      cache[uri] = null;
      String json;
      try {
        json = await read(uri);
      } catch (e) {
        throw new LibrariesSpecificationException(
            messageIncludePathCouldNotBeRead(uri, e));
      }
      return cache[uri] =
          await LibrariesSpecification.parse(uri, json, loadSpecification);
    }

    return loadSpecification(uri);
  }

  /// Parse the given [json] as a library specification, resolving any relative
  /// paths from [specUri].
  ///
  /// May throw an exception if [json] is not properly formatted or contains
  /// invalid values.
  static Future<LibrariesSpecification> parse(
      Uri specUri,
      String? json,
      Future<LibrariesSpecification> Function(Uri uri)
          loadSpecification) async {
    if (json == null) return new LibrariesSpecification(specUri);
    Map<String, dynamic> jsonData;
    try {
      dynamic data = jsonDecode(json);
      if (data is! Map<String, dynamic>) {
        return _reportError(messageTopLevelIsNotAMap(specUri));
      }
      jsonData = data;
    } on FormatException catch (e) {
      throw new LibrariesSpecificationException(e);
    }
    Map<String, TargetLibrariesSpecification> targets =
        <String, TargetLibrariesSpecification>{};

    Set<String> currentTargets = {};

    Future<TargetLibrariesSpecification> resolveTargetData(
        String targetName) async {
      TargetLibrariesSpecification? spec = targets[targetName];
      if (spec != null) {
        return spec;
      }
      if (currentTargets.contains(targetName)) {
        _reportError(messageCyclicInternalInclude(targetName, specUri));
      }

      currentTargets.add(targetName);
      Map<String, LibraryInfo> libraries = <String, LibraryInfo>{};
      Object? targetData = jsonData[targetName];
      if (targetData is! Map) {
        _reportError(messageTargetIsNotAMap(targetName, specUri));
      }

      Object? include = targetData["include"];
      if (include != null) {
        if (include is! List) {
          _reportError(messageIncludeIsNotAList(targetName, specUri));
        }
        for (Object? map in include) {
          if (map is! Map<String, dynamic>) {
            _reportError(messageIncludeEntryIsNotAMap(targetName, specUri));
          }
          if (!map.containsKey("target")) {
            _reportError(messageIncludeTargetMissing(targetName, specUri));
          }
          Object? target = map["target"];
          if (target is! String) {
            _reportError(messageIncludeTargetIsNotAString(targetName, specUri));
          }
          if (!map.containsKey("path")) {
            if (!jsonData.containsKey(target)) {
              _reportError(messageMissingTarget(target, specUri));
            }
            TargetLibrariesSpecification targetLibrariesSpecification =
                await resolveTargetData(target);
            libraries.addAll(targetLibrariesSpecification._libraries);
          } else {
            Object? path = map["path"];
            if (path is! String) {
              _reportError(messageIncludePathIsNotAString(targetName, specUri));
            }
            Uri uri = Uri.parse(path);
            if (uri.hasScheme && !uri.isScheme('file')) {
              return _reportError(messageUnsupportedUriScheme(path, specUri));
            }
            LibrariesSpecification specification =
                await loadSpecification(specUri.resolveUri(uri));
            TargetLibrariesSpecification targetSpecification =
                specification.specificationFor(target);
            for (LibraryInfo libraryInfo in targetSpecification.allLibraries) {
              libraries[libraryInfo.name] = libraryInfo;
            }
          }
        }
      }
      if (!targetData.containsKey("libraries")) {
        _reportError(messageTargetLibrariesMissing(targetName, specUri));
      }
      Object? librariesData = targetData["libraries"];
      if (librariesData is! Map<String, dynamic>) {
        _reportError(messageLibrariesEntryIsNotAMap(targetName, specUri));
      }
      librariesData.forEach((String libraryName, Object? data) {
        if (data is! Map<String, dynamic>) {
          _reportError(
              messageLibraryDataIsNotAMap(libraryName, targetName, specUri));
        }
        Uri checkAndResolve(Object? uriString) {
          if (uriString is! String) {
            return _reportError(messageLibraryUriIsNotAString(
                uriString, libraryName, targetName, specUri));
          }
          Uri uri = Uri.parse(uriString);
          if (uri.hasScheme && !uri.isScheme('file')) {
            return _reportError(
                messageUnsupportedUriScheme(uriString, specUri));
          }
          return specUri.resolveUri(uri);
        }

        if (!data.containsKey('uri')) {
          _reportError(
              messageLibraryUriMissing(libraryName, targetName, specUri));
        }
        Uri uri = checkAndResolve(data['uri']);
        List<Uri> patches;
        if (data['patches'] is List) {
          patches =
              data['patches'].map<Uri>((s) => specUri.resolve(s)).toList();
        } else if (data['patches'] is String) {
          patches = [checkAndResolve(data['patches'])];
        } else if (data['patches'] == null) {
          patches = const [];
        } else {
          _reportError(messagePatchesMustBeListOrString(libraryName));
        }

        dynamic supported = data['supported'] ?? true;
        if (supported is! bool) {
          _reportError(messageSupportedIsNotABool(supported));
        }
        libraries[libraryName] = new LibraryInfo(libraryName, uri, patches,
            // Internal libraries are never supported through conditional
            // imports and const `fromEnvironment` expressions.
            isSupported: supported && !libraryName.startsWith('_'));
      });
      currentTargets.remove(targetName);
      return targets[targetName] =
          new TargetLibrariesSpecification(targetName, libraries);
    }

    for (String targetName in jsonData.keys) {
      if (targetName.startsWith("comment:")) {
        continue;
      }
      await resolveTargetData(targetName);
    }
    return new LibrariesSpecification(specUri, targets);
  }

  static Never _reportError(String error) =>
      throw new LibrariesSpecificationException(error);

  /// Serialize this specification to json.
  ///
  /// If possible serializes paths relative to [outputUri].
  String toJsonString(Uri outputUri) => jsonEncode(toJsonMap(outputUri));

  Map toJsonMap(Uri outputUri) {
    Map result = {};
    Uri dir = outputUri.resolve('.');
    String pathFor(Uri uri) => relativizeUri(dir, uri, isWindows);
    _targets.forEach((targetName, target) {
      Map libraries = {};
      target._libraries.forEach((name, lib) {
        libraries[name] = {
          'uri': pathFor(lib.uri),
          'patches': lib.patches.map(pathFor).toList(),
        };
        if (!lib.isSupported) {
          libraries[name]['supported'] = false;
        }
      });
      result[targetName] = {'libraries': libraries};
    });
    return result;
  }
}

/// Specifies information about all libraries supported by a given target.
class TargetLibrariesSpecification {
  /// Name of the target platform.
  final String targetName;

  final Map<String, LibraryInfo> _libraries;

  const TargetLibrariesSpecification(this.targetName,
      [this._libraries = const <String, LibraryInfo>{}]);

  /// Details about a library whose import is `dart:$name`.
  LibraryInfo? libraryInfoFor(String name) => _libraries[name];

  Iterable<LibraryInfo> get allLibraries => _libraries.values;
}

/// Information about a `dart:` library in a specific target platform.
class LibraryInfo {
  /// The name of the library, which is the path developers use to import this
  /// library (as `dart:$name`).
  final String name;

  /// The file defining the main implementation of the library.
  final Uri uri;

  /// Patch files used for this library in the target platform, if any.
  final List<Uri> patches;

  /// Whether the library is supported and thus `dart.library.name` is "true"
  /// for conditional imports and fromEnvironment constants.
  final bool isSupported;

  const LibraryInfo(this.name, this.uri, this.patches,
      {this.isSupported: true});

  /// The import uri for the defined library.
  Uri get importUri => Uri.parse('dart:${name}');
}

class LibrariesSpecificationException {
  Object error;
  LibrariesSpecificationException(this.error);

  @override
  String toString() => '$error';
}

String messageMissingTarget(String targetName, Uri specUri) =>
    'No library specification for target "$targetName" in ${specUri}.';

String messageCyclicSpec(Uri specUri) => 'Cyclic dependency in ${specUri}.';

String messageCyclicInternalInclude(String targetName, Uri specUri) =>
    'Cyclic dependency of target "$targetName" in ${specUri}.';

String messageTopLevelIsNotAMap(Uri specUri) =>
    'Top-level specification is not a map in ${specUri}.';

String messageTargetIsNotAMap(String targetName, Uri specUri) =>
    'Target specification for "$targetName" is not a map in $specUri.';

String messageIncludeIsNotAList(String targetName, Uri specUri) =>
    '"include" specification for "$targetName" is not a list in $specUri.';

String messageIncludeEntryIsNotAMap(String targetName, Uri specUri) =>
    '"include" entry in "$targetName" is not a map in $specUri.';

String messageIncludePathIsNotAString(String targetName, Uri specUri) =>
    '"include" path in "$targetName" is not a string in  $specUri.';

String messageIncludePathCouldNotBeRead(Uri includeUri, Object error) =>
    '"include" path \'$includeUri\' could not be read: $error';

String messageIncludeTargetMissing(String targetName, Uri specUri) =>
    '"include" target in "$targetName" is missing in $specUri.';

String messageIncludeTargetIsNotAString(String targetName, Uri specUri) =>
    '"include" target in "$targetName" is not a string in $specUri.';

String messageTargetLibrariesMissing(String targetName, Uri specUri) =>
    'Target specification '
    'for "$targetName" doesn\'t have a libraries entry in $specUri.';

String messageLibrariesEntryIsNotAMap(String targetName, Uri specUri) =>
    '"libraries" entry for "$targetName" is not a map in $specUri.';

String messageLibraryDataIsNotAMap(
        String libraryName, String targetName, Uri specUri) =>
    'Library data for \'$libraryName\' in target "$targetName" is not a map '
    'in $specUri.';

String messageLibraryUriMissing(
        String libraryName, String targetName, Uri specUri) =>
    '"uri" is missing '
    'from library \'$libraryName\' in target "$targetName" in $specUri.';

String messageLibraryUriIsNotAString(
        Object? uriValue, String libraryName, String targetName, Uri specUri) =>
    'Uri value `$uriValue` is not a string '
    '(from library \'$libraryName\' in target "$targetName" in $specUri).';

String messageUnsupportedUriScheme(String uriValue, Uri specUri) =>
    "Uri scheme in '$uriValue' is not supported in $specUri.";

String messagePatchesMustBeListOrString(String libraryName) =>
    '"patches" entry for "$libraryName" is not a list or a string.';

String messageSupportedIsNotABool(Object supportedValue) =>
    '"supported" entry: expected a `bool` but '
    'got a `${supportedValue.runtimeType}` ("$supportedValue").';
