// 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 'common.dart';
import 'elements/elements.dart' show LibraryElement;
import 'util/emptyset.dart';

/// API used by the library loader to translate internal SDK URIs into file
/// system readable URIs.
abstract class ResolvedUriTranslator {
  factory ResolvedUriTranslator(
      Map<String, Uri> sdkLibraries,
      DiagnosticReporter reporter,
      Uri platformConfigUri) = _ResolvedUriTranslator;

  /// The set of platform libraries reported as unsupported.
  ///
  /// For instance when importing 'dart:io' without '--categories=Server'.
  Set<Uri> get disallowedLibraryUris;

  /// Whether or not a mockable library has been translated.
  bool get mockableLibraryUsed;

  /// A mapping from dart: library names to their location.
  Map<String, Uri> get sdkLibraries;

  /// Translates the resolved [uri] into a readable URI.
  ///
  /// The [importingLibrary] holds the library importing [uri] or `null` if
  /// [uri] is loaded as the main library. The [importingLibrary] is used to
  /// grant access to internal libraries from platform libraries and patch
  /// libraries.
  ///
  /// If the [uri] is not accessible from [importingLibrary], this method is
  /// responsible for reporting errors.
  ///
  /// See [LibraryLoader] for terminology on URIs.
  Uri translate(LibraryElement importingLibrary, Uri uri, Spannable spannable);
}

/// A translator that forwards all methods to an internal
/// [ResolvedUriTranslator].
///
/// The translator to forward to may be set after the instance is constructed.
/// This is useful for the compiler because some tasks that are instantiated at
/// compiler construction time need a [ResolvedUriTranslator], but the data
/// required to instantiate it cannot be obtained at construction time. So a
/// [ForwardingResolvedUriTranslator] may be passed instead, and the translator
/// to forward to can be set once the required data has been retrieved.
class ForwardingResolvedUriTranslator implements ResolvedUriTranslator {
  ResolvedUriTranslator resolvedUriTranslator;

  /// Returns `true` if [resolvedUriTranslator] is not `null`.
  bool get isSet => resolvedUriTranslator != null;

  /// The opposite of [isSet].
  bool get isNotSet => resolvedUriTranslator == null;

  @override
  Uri translate(LibraryElement importingLibrary, Uri resolvedUri,
          Spannable spannable) =>
      resolvedUriTranslator.translate(importingLibrary, resolvedUri, spannable);

  @override
  Set<Uri> get disallowedLibraryUris =>
      resolvedUriTranslator?.disallowedLibraryUris ??
      const ImmutableEmptySet<Uri>();

  @override
  bool get mockableLibraryUsed => resolvedUriTranslator.mockableLibraryUsed;

  @override
  Map<String, Uri> get sdkLibraries => resolvedUriTranslator.sdkLibraries;
}

class _ResolvedUriTranslator implements ResolvedUriTranslator {
  final Map<String, Uri> _sdkLibraries;
  final DiagnosticReporter _reporter;
  final Uri _platformConfigUri;

  Set<Uri> disallowedLibraryUris = new Set<Uri>();
  bool mockableLibraryUsed = false;

  _ResolvedUriTranslator(
      this._sdkLibraries, this._reporter, this._platformConfigUri);

  Map<String, Uri> get sdkLibraries => _sdkLibraries;

  @override
  Uri translate(LibraryElement importingLibrary, Uri uri, Spannable spannable) {
    if (uri.scheme == 'dart') {
      return translateDartUri(importingLibrary, uri, spannable);
    }
    return uri;
  }

  /// Translates "resolvedUri" with scheme "dart" to a [uri] resolved relative
  /// to `options.platformConfigUri` according to the information in the file at
  /// `options.platformConfigUri`.
  ///
  /// Returns `null` and emits an error if the library could not be found or
  /// imported into [importingLibrary].
  ///
  /// Internal libraries (whose name starts with '_') can be only resolved if
  /// [importingLibrary] is a platform or patch library.
  Uri translateDartUri(
      LibraryElement importingLibrary, Uri resolvedUri, Spannable spannable) {
    Uri location = lookupLibraryUri(resolvedUri.path);

    if (location == null) {
      _reporter.reportErrorMessage(spannable, MessageKind.LIBRARY_NOT_FOUND,
          {'resolvedUri': resolvedUri});
      return null;
    }

    if (resolvedUri.path.startsWith('_')) {
      bool allowInternalLibraryAccess = importingLibrary != null &&
          (importingLibrary.isPlatformLibrary ||
              importingLibrary.isPatch ||
              importingLibrary.canonicalUri.scheme == 'memory' ||
              importingLibrary.canonicalUri.path
                  .contains('tests/compiler/dart2js_native') ||
              importingLibrary.canonicalUri.path
                  .contains('tests/compiler/dart2js_extra') ||
              (importingLibrary.canonicalUri.scheme == 'package' &&
                  importingLibrary.canonicalUri.path
                      .startsWith('dart_internal/')));

      if (!allowInternalLibraryAccess) {
        if (importingLibrary != null) {
          _reporter.reportErrorMessage(
              spannable, MessageKind.INTERNAL_LIBRARY_FROM, {
            'resolvedUri': resolvedUri,
            'importingUri': importingLibrary.canonicalUri
          });
        } else {
          _reporter.reportErrorMessage(spannable, MessageKind.INTERNAL_LIBRARY,
              {'resolvedUri': resolvedUri});
          registerDisallowedLibraryUse(resolvedUri);
        }
        return null;
      }
    }

    if (location.scheme == "unsupported") {
      if (location.path == "") {
        _reporter.reportErrorMessage(spannable,
            MessageKind.LIBRARY_NOT_SUPPORTED, {'resolvedUri': resolvedUri});
        registerDisallowedLibraryUse(resolvedUri);
      } else {
        // If the specification includes a path, we treat it as "partially"
        // unsupported: it is allowed to be imported unconditionally, but we
        // will not expose it as being supported in the const variable
        // `dart.library.name`.
        //
        // This is a stopgap measure to support packages like `http` that need
        // to import `dart:io` conditionally. Once config-imports are supported
        // in the language, we can make it an error again to import it
        // unconditionally.
        //
        // The plaform configuration files contain a URI of the form
        // `unsupported:path/to/library.dart` to indicate this partially
        // supported mode. We resolve the path with respect to the configuration
        // file.
        return _platformConfigUri.resolve(location.path);
      }
      return null;
    }

    if (resolvedUri.path == 'html' || resolvedUri.path == 'io') {
      // TODO(ahe): Get rid of mockableLibraryUsed when test.dart
      // supports this use case better.
      mockableLibraryUsed = true;
    }
    return location;
  }

  void registerDisallowedLibraryUse(Uri uri) {
    disallowedLibraryUris.add(uri);
  }

  Uri lookupLibraryUri(String libraryName) {
    return _sdkLibraries[libraryName];
  }
}
