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

/// Helper library that creates an iframe sandbox that can be used to load
/// code.
library trydart.test.sandbox;

import 'dart:html';
import 'dart:async';

// TODO(ahe): Remove this import if issue 17936 is fixed.
import 'dart:js' as hack;

import 'package:expect/expect.dart' show
    Expect;

final Listener listener = new Listener();

void onError(String message, String filename, int lineno, [int colno, error]) {
  if (filename != null && filename != "" && lineno != 0) {
    if (colno != null && colno != 0) {
      message = '$filename:$lineno:$colno $message';
    } else {
      message = '$filename:$lineno: $message';
    }
  }
  if (error != null) {
    // See:
    // https://mikewest.org/2013/08/debugging-runtime-errors-with-window-onerror
    var stack = error['stack'];
    if (stack != null) {
      message += '\n$stack';
    }
  }
  message = "Error occurred in iframe: $message";

  // Synchronous, easier to read when running the browser manually.
  window.console.log(message);

  new Future(() {
    // Browsers ignore errors throw in event listeners (or from
    // window.onerror).
    throw message;
  });
}

void installErrorHandlerOn(IFrameElement iframe) {
  // This method uses dart:js to install an error event handler on the content
  // window of [iframe]. This is a workaround for http://dartbug.com/17936.
  var iframeProxy = new hack.JsObject.fromBrowserObject(iframe);
  var contentWindowProxy = iframeProxy['contentWindow'];
  if (contentWindowProxy == null) {
    print('No contentWindow in iframe');
    throw 'No contentWindow in iframe';
  }

  // Note: we have two options, use "iframe.contentWindow.onerror = ..." or
  // "iframe.contentWindow.addEventListener('error', ...)".  The former seems
  // to provide more details on both Chrome and Firefox (which provides no
  // information at all in error events).
  contentWindowProxy['onerror'] = onError;
}

void onIframeLoaded(Event event) {
  installErrorHandlerOn(event.target);
}

IFrameElement appendIFrame(String src, Element element) {
  IFrameElement iframe = new IFrameElement()
      ..src = src
      ..onLoad.listen(onIframeLoaded);
  element.append(iframe);
  // Install an error handler both on the new iframe element, and when it has
  // fired the load event.  That seems to matter according to some sources on
  // stackoverflow.
  installErrorHandlerOn(iframe);
  return iframe;
}

class Listener {
  Completer completer;

  String expectedMessage;

  Stopwatch wallclock;

  int get elapsed => wallclock.elapsedMilliseconds ~/ 1000;

  void onMessage(MessageEvent e) {
    String message = e.data;
    if (expectedMessage == message) {
      completer.complete();
    } else {
      switch (message) {
        case 'dart-calling-main':
        case 'dart-main-done':
        case 'unittest-suite-done':
        case 'unittest-suite-fail':
        case 'unittest-suite-success':
        case 'unittest-suite-wait-for-done':
          break;

        default:
          completer.completeError(
              'Unexpected message: "$message" (expected "$expectedMessage").');
      }
    }
  }

  Future expect(data) {
    if (data is String) {
      Expect.isTrue(completer == null || completer.isCompleted);
      expectedMessage = data;
      completer = new Completer();
      return completer.future;
    } else if (data is Iterable) {
      return Future.forEach(data, expect);
    } else {
      throw 'Unexpected data type: ${data.runtimeType}.';
    }
  }

  void start() {
    wallclock = new Stopwatch()..start();
    window.onMessage.listen(onMessage);
  }
}
