// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// ignore_for_file: avoid_dynamic_calls

@JS()
library test.host;

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

import 'package:js/js.dart';
import 'package:stack_trace/stack_trace.dart';
import 'package:stream_channel/stream_channel.dart';
// ignore: implementation_imports
import 'package:ui/src/engine/dom.dart';

/// A class defined in content shell, used to control its behavior.
@JS()
@staticInterop
class _TestRunner {}

extension _TestRunnerExtension on _TestRunner {
  external void waitUntilDone();
}

/// Returns the current content shell runner, or `null` if none exists.
@JS()
external _TestRunner? get testRunner; // ignore: library_private_types_in_public_api

/// A class that exposes the test API to JS.
///
/// These are exposed so that tools like IDEs can interact with them via remote
/// debugging.
@JS()
@anonymous
@staticInterop
class _JSApi {
  external factory _JSApi({void Function() resume, void Function() restartCurrent});
}

extension _JSApiExtension on _JSApi {
  /// Causes the test runner to resume running, as though the user had clicked
  /// the "play" button.
  // ignore: unused_element
  external Function get resume;

  /// Causes the test runner to restart the current test once it finishes
  /// running.
  // ignore: unused_element
  external Function get restartCurrent;
}

/// Sets the top-level `dartTest` object so that it's visible to JS.
@JS('dartTest')
external set _jsApi(_JSApi api);

/// The iframes created for each loaded test suite, indexed by the suite id.
final Map<int, DomHTMLIFrameElement> _iframes = <int, DomHTMLIFrameElement>{};

/// Subscriptions created for each loaded test suite, indexed by the suite id.
final Map<int, List<DomSubscription>> _domSubscriptions = <int, List<DomSubscription>>{};
final Map<int, List<StreamSubscription<dynamic>>> _streamSubscriptions =<int, List<StreamSubscription<dynamic>>>{};

/// The URL for the current page.
final Uri _currentUrl = Uri.parse(domWindow.location.href);

/// Code that runs in the browser and loads test suites at the server's behest.
///
/// One instance of this runs for each browser. When the server tells it to load
/// a test, it starts an iframe pointing at that test's code; from then on, it
/// just relays messages between the two.
///
/// The browser uses two layers of [MultiChannel]s when communicating with the
/// server:
///
///                                       server
///                                         │
///                                    (WebSocket)
///                                         │
///                    ┏━ host.html ━━━━━━━━┿━━━━━━━━━━━━━━━━━┓
///                    ┃                    │                 ┃
///                    ┃    ┌──────┬───MultiChannel─────┐     ┃
///                    ┃    │      │      │      │      │     ┃
///                    ┃   host  suite  suite  suite  suite   ┃
///                    ┃           │      │      │      │     ┃
///                    ┗━━━━━━━━━━━┿━━━━━━┿━━━━━━┿━━━━━━┿━━━━━┛
///                                │      │      │      │
///                                │     ...    ...    ...
///                                │
///                         (MessageChannel)
///                                │
///      ┏━ suite.html (in iframe) ┿━━━━━━━━━━━━━━━━━━━━━━━━━━┓
///      ┃                         │                          ┃
///      ┃         ┌──────────MultiChannel┬─────────┐         ┃
///      ┃         │          │     │     │         │         ┃
///      ┃   IframeListener  test  test  test  running test   ┃
///      ┃                                                    ┃
///      ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
///
/// The host (this code) has a [MultiChannel] that splits the WebSocket
/// connection with the server. One connection is used for the host itself to
/// receive messages like "load a suite at this URL", and the rest are
/// connected to each test suite's iframe via a [MessageChannel].
///
/// Each iframe then has its own [MultiChannel] which takes its
/// [MessageChannel] connection and splits it again. One connection is used for
/// the [IframeListener], which sends messages like "here are all the tests in
/// this suite". The rest are used for each test, receiving messages like
/// "start running". A new connection is also created whenever a test begins
/// running to send status messages about its progress.
///
/// It's of particular note that the suite's [MultiChannel] connection uses the
/// host's purely as a transport layer; neither is aware that the other is also
/// using [MultiChannel]. This is necessary, since the host doesn't share memory
/// with the suites and thus can't share its [MultiChannel] with them, but it
/// does mean that the server needs to be sure to nest its [MultiChannel]s at
/// the same place the client does.
void main() {
  // This tells content_shell not to close immediately after the page has
  // rendered.
  testRunner?.waitUntilDone();

  if (_currentUrl.queryParameters['debug'] == 'true') {
    domDocument.body!.classList.add('debug');
  }

  runZonedGuarded(
    () {
      final MultiChannel<dynamic> serverChannel = _connectToServer();
      serverChannel.stream.listen((dynamic message) {
        if (message['command'] == 'loadSuite') {
          final int channelId = message['channel'] as int;
          final String url = message['url'] as String;
          final int messageId = message['id'] as int;
          final VirtualChannel<dynamic> suiteChannel = serverChannel.virtualChannel(channelId);
          final StreamChannel<dynamic> iframeChannel = _connectToIframe(url, messageId);
          suiteChannel.pipe(iframeChannel);
        } else if (message['command'] == 'displayPause') {
          domDocument.body!.classList.add('paused');
        } else if (message['command'] == 'resume') {
          domDocument.body!.classList.remove('paused');
        } else {
          assert(message['command'] == 'closeSuite');
          _iframes.remove(message['id'])!.remove();

          for (final DomSubscription subscription in _domSubscriptions.remove(message['id'])!) {
            subscription.cancel();
          }
          for (final StreamSubscription<dynamic> subscription in _streamSubscriptions.remove(message['id'])!) {
            subscription.cancel();
          }
        }
      });

      // Send periodic pings to the test runner so it can know when the browser is
      // paused for debugging.
      Timer.periodic(const Duration(seconds: 1),
          (_) => serverChannel.sink.add(<String, String>{'command': 'ping'}));

      _jsApi = _JSApi(resume: allowInterop(() {
        if (!domDocument.body!.classList.contains('paused')) {
          return;
        }
        domDocument.body!.classList.remove('paused');
        serverChannel.sink.add(<String, String>{'command': 'resume'});
      }), restartCurrent: allowInterop(() {
        serverChannel.sink.add(<String, String>{'command': 'restart'});
      }));
    },
    (dynamic error, StackTrace stackTrace) {
      print('$error\n${Trace.from(stackTrace).terse}'); // ignore: avoid_print
    },
  );
}

/// Creates a [MultiChannel] connection to the server, using a [WebSocket] as
/// the underlying protocol.
MultiChannel<dynamic> _connectToServer() {
  // The `managerUrl` query parameter contains the WebSocket URL of the remote
  // [BrowserManager] with which this communicates.
  final DomWebSocket webSocket = createDomWebSocket(_currentUrl.queryParameters['managerUrl']!);

  final StreamChannelController<dynamic> controller = StreamChannelController<dynamic>(sync: true);
  webSocket.addEventListener('message', allowInterop((DomEvent message) {
    final String data = (message as DomMessageEvent).data as String;
    controller.local.sink.add(jsonDecode(data));
  }));

  controller.local.stream
      .listen((dynamic message) => webSocket.send(jsonEncode(message)));

  return MultiChannel<dynamic>(controller.foreign);
}

/// Creates an iframe with `src` [url] and establishes a connection to it using
/// a [MessageChannel].
///
/// [id] identifies the suite loaded in this iframe.
StreamChannel<dynamic> _connectToIframe(String url, int id) {
  final DomHTMLIFrameElement iframe = createDomHTMLIFrameElement();
  _iframes[id] = iframe;
  iframe
    ..src = url
    ..width = '1000'
    ..height = '1000';
  domDocument.body!.appendChild(iframe);

  // Use this to communicate securely with the iframe.
  final DomMessageChannel channel = createDomMessageChannel();
  final StreamChannelController<dynamic> controller = StreamChannelController<dynamic>(sync: true);

  // Use this to avoid sending a message to the iframe before it's sent a
  // message to us. This ensures that no messages get dropped on the floor.
  final Completer<dynamic> readyCompleter = Completer<dynamic>();

  final List<DomSubscription> domSubscriptions = <DomSubscription>[];
  final List<StreamSubscription<dynamic>> streamSubscriptions = <StreamSubscription<dynamic>>[];
  _domSubscriptions[id] = domSubscriptions;
  _streamSubscriptions[id] = streamSubscriptions;
  domSubscriptions.add(DomSubscription(domWindow, 'message',
          allowInterop((DomEvent event) {
    final DomMessageEvent message = event as DomMessageEvent;
    // A message on the Window can theoretically come from any website. It's
    // very unlikely that a malicious site would care about hacking someone's
    // unit tests, let alone be able to find the test server while it's
    // running, but it's good practice to check the origin anyway.
    if (message.origin != domWindow.location.origin) {
      return;
    }

    if (message.data['href'] != iframe.src) {
      return;
    }

    message.stopPropagation();

    if (message.data['ready'] == true) {
      // This message indicates that the iframe is actively listening for
      // events, so the message channel's second port can now be transferred.
      channel.port2.start();
      iframe.contentWindow.postMessage('port', domWindow.location.origin,
          <DomMessagePort>[channel.port2]);
      readyCompleter.complete();
    } else if (message.data['exception'] == true) {
      // This message from `dart.js` indicates that an exception occurred
      // loading the test.
      controller.local.sink.add(message.data['data']);
    }
  })));

  channel.port1.start();
  domSubscriptions.add(DomSubscription(channel.port1, 'message',
          allowInterop((DomEvent message) {
    controller.local.sink.add((message as DomMessageEvent).data['data']);
  })));

  streamSubscriptions.add(controller.local.stream.listen((dynamic message) async {
    await readyCompleter.future;
    channel.port1.postMessage(message);
  }));

  return controller.foreign;
}
