// 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) =
      _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;

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

  _ResolvedUriTranslator(this._sdkLibraries, this._reporter);

  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.path
                  .contains('sdk/tests/compiler/dart2js_native'));

      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") {
      _reporter.reportErrorMessage(spannable, MessageKind.LIBRARY_NOT_SUPPORTED,
          {'resolvedUri': resolvedUri});
      registerDisallowedLibraryUse(resolvedUri);
      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];
  }
}
