// Copyright (c) 2014, 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.

// Helpers for writing compiler tests running in browser.
library trydart.web_compiler_test_case;

import 'dart:async' show
    EventSink,
    Future;

import 'dart:html' show
    HttpRequest;

import '../poi/compiler_test_case.dart' show
    customUri,
    CompilerTestCase;

import 'package:dart2js_incremental/dart2js_incremental.dart' show
    IncrementalCompiler;

import 'package:compiler/compiler.dart' show
    Diagnostic;

const String WEB_SCHEME = 'org.trydart.web';

/// A CompilerTestCase which runs in a browser.
class WebCompilerTestCase extends CompilerTestCase {
  final IncrementalCompiler incrementalCompiler;

  WebCompilerTestCase.init(String source, Uri uri)
      : this.incrementalCompiler = makeCompiler(source, uri),
        super.init(source, uri, null);

  WebCompilerTestCase(String source, [String path])
      : this.init(source, customUri(path == null ? 'main.dart' : path));

  Future run() {
    return incrementalCompiler.compile(scriptUri).then((success) {
      if (!success) throw 'Compilation failed';
      OutputProvider outputProvider = incrementalCompiler.outputProvider;
      return outputProvider['.js'];
    });
  }

  static IncrementalCompiler makeCompiler(String source, Uri mainUri) {
    Uri libraryRoot = new Uri(scheme: WEB_SCHEME, path: '/sdk/');
    Uri packageRoot = new Uri(scheme: WEB_SCHEME, path: '/packages/');
    WebInputProvider inputProvider =
        new WebInputProvider(source, mainUri, libraryRoot, packageRoot);

    void diagnosticHandler(
        Uri uri, int begin, int end, String message, Diagnostic kind) {
      if (uri == null) {
        print('[$kind] $message');
      } else {
        print('$uri@$begin+${end - begin}: [$kind] $message');
      }
    }

    return new IncrementalCompiler(
        libraryRoot: libraryRoot,
        packageRoot: packageRoot,
        inputProvider: inputProvider,
        diagnosticHandler: diagnosticHandler,
        outputProvider: new OutputProvider());
  }
}

/// An input provider which provides input via [HttpRequest].
/// Includes one in-memory compilation unit [source] which is returned when
/// [mainUri] is requested.
class WebInputProvider {
  final String source;

  final Uri mainUri;

  final Uri libraryRoot;

  final Uri packageRoot;

  final Map<Uri, Future> cachedSources = new Map<Uri, Future>();

  static final Map<String, Future> cachedRequests = new Map<String, Future>();

  WebInputProvider(
      this.source, this.mainUri, this.libraryRoot, this.packageRoot);

  Future call(Uri uri) {
    return cachedSources.putIfAbsent(uri, () {
      if (uri == mainUri) return new Future.value(source);
      if (uri.scheme == WEB_SCHEME) {
        return cachedHttpRequest('/root_dart${uri.path}');
      } else {
        return cachedHttpRequest('$uri');
      }
    });
  }

  static Future cachedHttpRequest(String uri) {
    return cachedRequests.putIfAbsent(uri, () => HttpRequest.getString(uri));
  }
}

/// Output provider which collect output in [output].
class OutputProvider {
  final Map<String, String> output = new Map<String, String>();

  EventSink<String> call(String name, String extension) {
    return new StringEventSink((String data) {
      output['$name.$extension'] = data;
    });
  }

  String operator[] (String key) => output[key];
}

/// Helper class to collect sources.
class StringEventSink implements EventSink<String> {
  List<String> data = <String>[];

  final Function onClose;

  StringEventSink(this.onClose);

  void add(String event) {
    if (data == null) throw 'StringEventSink is closed.';
    data.add(event);
  }

  void addError(errorEvent, [StackTrace stackTrace]) {
    throw 'addError($errorEvent, $stackTrace)';
  }

  void close() {
    if (data != null) {
      onClose(data.join());
      data = null;
    }
  }
}
