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

library leg_apiimpl;

import 'dart:async';
import 'dart:convert';

import 'package:package_config/packages.dart';
import 'package:package_config/packages_file.dart' as pkgs;
import 'package:package_config/src/packages_impl.dart' show
    MapPackages,
    NonFilePackagesDirectoryPackages;
import 'package:package_config/src/util.dart' show
    checkValidPackageUri;

import '../compiler_new.dart' as api;
import 'commandline_options.dart';
import 'common.dart';
import 'common/tasks.dart' show
    GenericTask;
import 'compiler.dart';
import 'diagnostics/diagnostic_listener.dart' show
    DiagnosticOptions;
import 'diagnostics/messages.dart' show
    Message;
import 'elements/elements.dart' as elements;
import 'io/source_file.dart';
import 'platform_configuration.dart' as platform_configuration;
import 'script.dart';

const bool forceIncrementalSupport =
    const bool.fromEnvironment('DART2JS_EXPERIMENTAL_INCREMENTAL_SUPPORT');

/// Locations of the platform descriptor files relative to the library root.
const String _clientPlatform = "lib/dart_client.platform";
const String _serverPlatform = "lib/dart_server.platform";
const String _sharedPlatform = "lib/dart_shared.platform";
const String _dart2dartPlatform = "lib/dart2dart.platform";

/// Implements the [Compiler] using a [api.CompilerInput] for supplying the
/// sources.
class CompilerImpl extends Compiler {
  api.CompilerInput provider;
  api.CompilerDiagnostics handler;
  final Uri platformConfigUri;
  final Uri packageConfig;
  final Uri packageRoot;
  final api.PackagesDiscoveryProvider packagesDiscoveryProvider;
  Packages packages;
  List<String> options;
  Map<String, dynamic> environment;
  bool mockableLibraryUsed = false;

  /// A mapping of the dart: library-names to their location.
  ///
  /// Initialized in [setupSdk].
  Map<String, Uri> sdkLibraries;

  GenericTask userHandlerTask;
  GenericTask userProviderTask;
  GenericTask userPackagesDiscoveryTask;

  Uri get libraryRoot => platformConfigUri.resolve(".");

  CompilerImpl(this.provider,
           api.CompilerOutput outputProvider,
           this.handler,
           Uri libraryRoot,
           this.packageRoot,
           List<String> options,
           this.environment,
           [this.packageConfig,
            this.packagesDiscoveryProvider])
      : this.options = options,
        this.platformConfigUri = resolvePlatformConfig(libraryRoot, options),
        super(
            outputProvider: outputProvider,
            enableTypeAssertions: hasOption(options, Flags.enableCheckedMode),
            enableUserAssertions: hasOption(options, Flags.enableCheckedMode),
            trustTypeAnnotations:
                hasOption(options, Flags.trustTypeAnnotations),
            trustPrimitives:
                hasOption(options, Flags.trustPrimitives),
            trustJSInteropTypeAnnotations:
                hasOption(options, Flags.trustJSInteropTypeAnnotations),
            enableMinification: hasOption(options, Flags.minify),
            useFrequencyNamer:
                !hasOption(options, Flags.noFrequencyBasedMinification),
            preserveUris: hasOption(options, Flags.preserveUris),
            enableNativeLiveTypeAnalysis:
                !hasOption(options, Flags.disableNativeLiveTypeAnalysis),
            emitJavaScript: !(hasOption(options, '--output-type=dart') ||
                              hasOption(options, '--output-type=dart-multi')),
            dart2dartMultiFile: hasOption(options, '--output-type=dart-multi'),
            generateSourceMap: !hasOption(options, Flags.noSourceMaps),
            analyzeAllFlag: hasOption(options, Flags.analyzeAll),
            analyzeOnly: hasOption(options, Flags.analyzeOnly),
            analyzeMain: hasOption(options, Flags.analyzeMain),
            analyzeSignaturesOnly:
                hasOption(options, Flags.analyzeSignaturesOnly),
            strips: extractCsvOption(options, '--force-strip='),
            disableTypeInferenceFlag:
                hasOption(options, Flags.disableTypeInference),
            preserveComments: hasOption(options, Flags.preserveComments),
            useCpsIr: hasOption(options, Flags.useCpsIr),
            verbose: hasOption(options, Flags.verbose),
            sourceMapUri: extractUriOption(options, '--source-map='),
            outputUri: extractUriOption(options, '--out='),
            deferredMapUri: extractUriOption(options, '--deferred-map='),
            dumpInfo: hasOption(options, Flags.dumpInfo),
            buildId: extractStringOption(
                options, '--build-id=',
                "build number could not be determined"),
            useContentSecurityPolicy:
              hasOption(options, Flags.useContentSecurityPolicy),
            useStartupEmitter: hasOption(options, Flags.fastStartup),
            hasIncrementalSupport:
                forceIncrementalSupport ||
                hasOption(options, Flags.incrementalSupport),
            diagnosticOptions: new DiagnosticOptions(
                suppressWarnings: hasOption(options, Flags.suppressWarnings),
                fatalWarnings: hasOption(options, Flags.fatalWarnings),
                suppressHints: hasOption(options, Flags.suppressHints),
                terseDiagnostics: hasOption(options, Flags.terse),
                showPackageWarnings:
                    hasOption(options, Flags.showPackageWarnings)),
            enableExperimentalMirrors:
                hasOption(options, Flags.enableExperimentalMirrors),
            enableAssertMessage:
                hasOption(options, Flags.enableAssertMessage),
            generateCodeWithCompileTimeErrors:
                hasOption(options, Flags.generateCodeWithCompileTimeErrors),
            testMode: hasOption(options, Flags.testMode),
            allowNativeExtensions:
                hasOption(options, Flags.allowNativeExtensions)) {
    tasks.addAll([
        userHandlerTask = new GenericTask('Diagnostic handler', this),
        userProviderTask = new GenericTask('Input provider', this),
        userPackagesDiscoveryTask =
            new GenericTask('Package discovery', this),
    ]);
    if (libraryRoot == null) {
      throw new ArgumentError("[libraryRoot] is null.");
    }
    if (!libraryRoot.path.endsWith("/")) {
      throw new ArgumentError("[libraryRoot] must end with a /.");
    }
    if (packageRoot != null && packageConfig != null) {
      throw new ArgumentError("Only one of [packageRoot] or [packageConfig] "
                              "may be given.");
    }
    if (packageRoot != null && !packageRoot.path.endsWith("/")) {
      throw new ArgumentError("[packageRoot] must end with a /.");
    }
    if (!analyzeOnly) {
      if (allowNativeExtensions) {
        throw new ArgumentError(
            "${Flags.allowNativeExtensions} is only supported in combination "
            "with ${Flags.analyzeOnly}");
      }
    }
  }

  static String extractStringOption(List<String> options,
                                    String prefix,
                                    String defaultValue) {
    for (String option in options) {
      if (option.startsWith(prefix)) {
        return option.substring(prefix.length);
      }
    }
    return defaultValue;
  }

  static Uri extractUriOption(List<String> options, String prefix) {
    var option = extractStringOption(options, prefix, null);
    return (option == null) ? null : Uri.parse(option);
  }

  // CSV: Comma separated values.
  static List<String> extractCsvOption(List<String> options, String prefix) {
    for (String option in options) {
      if (option.startsWith(prefix)) {
        return option.substring(prefix.length).split(',');
      }
    }
    return const <String>[];
  }

  static Uri resolvePlatformConfig(Uri libraryRoot,
                                   List<String> options) {
    String platformConfigPath =
        extractStringOption(options, "--platform-config=", null);
    if (platformConfigPath != null) {
      return libraryRoot.resolve(platformConfigPath);
    } else if (hasOption(options, '--output-type=dart')) {
      return libraryRoot.resolve(_dart2dartPlatform);
    } else {
      Iterable<String> categories = extractCsvOption(options, '--categories=');
      if (categories.length == 0) {
        return libraryRoot.resolve(_clientPlatform);
      }
      assert(categories.length <= 2);
      if (categories.contains("Client")) {
        if (categories.contains("Server")) {
          return libraryRoot.resolve(_sharedPlatform);
        }
        return libraryRoot.resolve(_clientPlatform);
      }
      assert(categories.contains("Server"));
      return libraryRoot.resolve(_serverPlatform);
    }
  }

  static bool hasOption(List<String> options, String option) {
    return options.indexOf(option) >= 0;
  }

  void log(message) {
    callUserHandler(
        null, null, null, null, message, api.Diagnostic.VERBOSE_INFO);
  }

  /// See [Compiler.translateResolvedUri].
  Uri translateResolvedUri(elements.LibraryElement importingLibrary,
                           Uri resolvedUri, Spannable spannable) {
    if (resolvedUri.scheme == 'dart') {
      return translateDartUri(importingLibrary, resolvedUri, spannable);
    }
    return resolvedUri;
  }

  /**
   * Reads the script designated by [readableUri].
   */
  Future<Script> readScript(Spannable node, Uri readableUri) {
    if (!readableUri.isAbsolute) {
      if (node == null) node = NO_LOCATION_SPANNABLE;
      reporter.internalError(node,
          'Relative uri $readableUri provided to readScript(Uri).');
    }

    // We need to store the current element since we are reporting read errors
    // asynchronously and therefore need to restore the current element for
    // [node] to be valid.
    elements.Element element = currentElement;
    void reportReadError(exception) {
      if (element == null || node == null) {
        reporter.reportErrorMessage(
            new SourceSpan(readableUri, 0, 0),
            MessageKind.READ_SELF_ERROR,
            {'uri': readableUri, 'exception': exception});
      } else {
        reporter.withCurrentElement(element, () {
          reporter.reportErrorMessage(
              node,
              MessageKind.READ_SCRIPT_ERROR,
              {'uri': readableUri, 'exception': exception});
        });
      }
    }

    Uri resourceUri = translateUri(node, readableUri);
    if (resourceUri == null) return synthesizeScript(node, readableUri);
    if (resourceUri.scheme == 'dart-ext') {
      if (!allowNativeExtensions) {
        reporter.withCurrentElement(element, () {
          reporter.reportErrorMessage(
              node, MessageKind.DART_EXT_NOT_SUPPORTED);
        });
      }
      return synthesizeScript(node, readableUri);
    }

    // TODO(johnniwinther): Wrap the result from [provider] in a specialized
    // [Future] to ensure that we never execute an asynchronous action without
    // setting up the current element of the compiler.
    return new Future.sync(() => callUserProvider(resourceUri)).then((data) {
      SourceFile sourceFile;
      if (data is List<int>) {
        sourceFile = new Utf8BytesSourceFile(resourceUri, data);
      } else if (data is String) {
        sourceFile = new StringSourceFile.fromUri(resourceUri, data);
      } else {
        String message = "Expected a 'String' or a 'List<int>' from the input "
                         "provider, but got: ${Error.safeToString(data)}.";
        reportReadError(message);
      }
      // We use [readableUri] as the URI for the script since need to preserve
      // the scheme in the script because [Script.uri] is used for resolving
      // relative URIs mentioned in the script. See the comment on
      // [LibraryLoader] for more details.
      return new Script(readableUri, resourceUri, sourceFile);
    }).catchError((error) {
      reportReadError(error);
      return synthesizeScript(node, readableUri);
    });
  }

  Future<Script> synthesizeScript(Spannable node, Uri readableUri) {
    return new Future.value(
        new Script(
            readableUri, readableUri,
            new StringSourceFile.fromUri(
                readableUri,
                "// Synthetic source file generated for '$readableUri'."),
            isSynthesized: true));
  }

  /**
   * Translates a readable URI into a resource URI.
   *
   * See [LibraryLoader] for terminology on URIs.
   */
  Uri translateUri(Spannable node, Uri readableUri) {
    switch (readableUri.scheme) {
      case 'package': return translatePackageUri(node, readableUri);
      default: return readableUri;
    }
  }

  /// Translates "resolvedUri" with scheme "dart" to a [uri] resolved relative
  /// to [platformConfigUri] according to the information in the file at
  /// [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(elements.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;
  }

  Uri translatePackageUri(Spannable node, Uri uri) {
    try {
      checkValidPackageUri(uri);
    } on ArgumentError catch (e) {
      reporter.reportErrorMessage(
          node,
          MessageKind.INVALID_PACKAGE_URI,
          {'uri': uri, 'exception': e.message});
      return null;
    }
    return packages.resolve(uri,
        notFound: (Uri notFound) {
          reporter.reportErrorMessage(
              node,
              MessageKind.LIBRARY_NOT_FOUND,
              {'resolvedUri': uri});
          return null;
        });
  }

  Future<elements.LibraryElement> analyzeUri(
      Uri uri,
      {bool skipLibraryWithPartOfTag: true}) {
    List<Future> setupFutures = new List<Future>();
    if (sdkLibraries == null) {
      setupFutures.add(setupSdk());
    }
    if (packages == null) {
      setupFutures.add(setupPackages(uri));
    }
    return Future.wait(setupFutures).then((_) => super.analyzeUri(uri));
  }

  Future setupPackages(Uri uri) {
    if (packageRoot != null) {
      // Use "non-file" packages because the file version requires a [Directory]
      // and we can't depend on 'dart:io' classes.
      packages = new NonFilePackagesDirectoryPackages(packageRoot);
    } else if (packageConfig != null) {
      return callUserProvider(packageConfig).then((packageConfigContents) {
        if (packageConfigContents is String) {
          packageConfigContents = UTF8.encode(packageConfigContents);
        }
        // The input provider may put a trailing 0 byte when it reads a source
        // file, which confuses the package config parser.
        if (packageConfigContents.length > 0 &&
            packageConfigContents.last == 0) {
          packageConfigContents = packageConfigContents.sublist(
              0, packageConfigContents.length - 1);
        }
        packages =
            new MapPackages(pkgs.parse(packageConfigContents, packageConfig));
      }).catchError((error) {
        reporter.reportErrorMessage(
            NO_LOCATION_SPANNABLE,
            MessageKind.INVALID_PACKAGE_CONFIG,
            {'uri': packageConfig, 'exception': error});
        packages = Packages.noPackages;
      });
    } else {
      if (packagesDiscoveryProvider == null) {
        packages = Packages.noPackages;
      } else {
        return callUserPackagesDiscovery(uri).then((p) {
          packages = p;
        });
      }
    }
    return new Future.value();
  }

  Future<Null> setupSdk() {
    if (sdkLibraries == null) {
      return platform_configuration.load(platformConfigUri, provider)
          .then((Map<String, Uri> mapping) {
        sdkLibraries = mapping;
      });
    } else {
      // The incremental compiler sets up the sdk before run.
      // Therefore this will be called a second time.
      return new Future.value(null);
    }
  }

  Future<bool> run(Uri uri) {
    log('Using platform configuration at ${platformConfigUri}');

    return Future.wait([setupSdk(), setupPackages(uri)]).then((_) {
      assert(sdkLibraries != null);
      assert(packages != null);

      return super.run(uri).then((bool success) {
        int cumulated = 0;
        for (final task in tasks) {
          int elapsed = task.timing;
          if (elapsed != 0) {
            cumulated += elapsed;
            log('${task.name} took ${elapsed}msec');
            for (String subtask in task.subtasks) {
              int subtime = task.getSubtaskTime(subtask);
              log('${task.name} > $subtask took ${subtime}msec');
            }
          }
        }
        int total = totalCompileTime.elapsedMilliseconds;
        log('Total compile-time ${total}msec;'
            ' unaccounted ${total - cumulated}msec');
        return success;
      });
    });
  }

  void reportDiagnostic(DiagnosticMessage message,
                        List<DiagnosticMessage> infos,
                        api.Diagnostic kind) {
    _reportDiagnosticMessage(message, kind);
    for (DiagnosticMessage info in infos) {
      _reportDiagnosticMessage(info, api.Diagnostic.INFO);
    }
  }

  void _reportDiagnosticMessage(DiagnosticMessage diagnosticMessage,
                                api.Diagnostic kind) {
    // [:span.uri:] might be [:null:] in case of a [Script] with no [uri]. For
    // instance in the [Types] constructor in typechecker.dart.
    SourceSpan span = diagnosticMessage.sourceSpan;
    Message message = diagnosticMessage.message;
    if (span == null || span.uri == null) {
      callUserHandler(message, null, null, null, '$message', kind);
    } else {
      callUserHandler(
          message, span.uri, span.begin, span.end, '$message', kind);
    }
  }

  bool get isMockCompilation {
    return mockableLibraryUsed
      && (options.indexOf(Flags.allowMockCompilation) != -1);
  }

  void callUserHandler(Message message, Uri uri, int begin, int end,
                       String text, api.Diagnostic kind) {
    try {
      userHandlerTask.measure(() {
        handler.report(message, uri, begin, end, text, kind);
      });
    } catch (ex, s) {
      diagnoseCrashInUserCode(
          'Uncaught exception in diagnostic handler', ex, s);
      rethrow;
    }
  }

  Future callUserProvider(Uri uri) {
    try {
      return userProviderTask.measure(() => provider.readFromUri(uri));
    } catch (ex, s) {
      diagnoseCrashInUserCode('Uncaught exception in input provider', ex, s);
      rethrow;
    }
  }

  Future<Packages> callUserPackagesDiscovery(Uri uri) {
    try {
      return userPackagesDiscoveryTask.measure(
                 () => packagesDiscoveryProvider(uri));
    } catch (ex, s) {
      diagnoseCrashInUserCode('Uncaught exception in package discovery', ex, s);
      rethrow;
    }
  }

  fromEnvironment(String name) => environment[name];

  Uri lookupLibraryUri(String libraryName) {
    assert(invariant(NO_LOCATION_SPANNABLE,
        sdkLibraries != null, message: "setupSdk() has not been run"));
    return sdkLibraries[libraryName];
  }

  Uri resolvePatchUri(String libraryName) {
    return backend.resolvePatchUri(libraryName, platformConfigUri);
  }
}
