// 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 'dart:async';

import 'package:async/async.dart';
import 'package:stream_channel/stream_channel.dart';
import 'package:term_glyph/term_glyph.dart' as glyph;

import 'package:test_api/src/backend/declarer.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/group.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/invoker.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/live_test.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/metadata.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/stack_trace_formatter.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/suite.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/suite_platform.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/test.dart'; // ignore: implementation_imports
import 'package:test_api/src/util/remote_exception.dart'; // ignore: implementation_imports

import 'suite_channel_manager.dart';

class RemoteListener {
  /// The test suite to run.
  final Suite _suite;

  /// The zone to forward prints to, or `null` if prints shouldn't be forwarded.
  final Zone? _printZone;

  /// Extracts metadata about all the tests in the function returned by
  /// [getMain] and returns a channel that will send information about them.
  ///
  /// The main function is wrapped in a closure so that we can handle it being
  /// undefined here rather than in the generated code.
  ///
  /// Once that's done, this starts listening for commands about which tests to
  /// run.
  ///
  /// If [hidePrints] is `true` (the default), calls to `print()` within this
  /// suite will not be forwarded to the parent zone's print handler. However,
  /// the caller may want them to be forwarded in (for example) a browser
  /// context where they'll be visible in the development console.
  ///
  /// If [beforeLoad] is passed, it's called before the tests have been declared
  /// for this worker.
  static StreamChannel<Object?> start(Function Function() getMain,
      {bool hidePrints = true,
      Future Function(
              StreamChannel<Object?> Function(String name) suiteChannel)?
          beforeLoad}) {
    // Synchronous in order to allow `print` output to show up immediately, even
    // if they are followed by long running synchronous work.
    var controller =
        StreamChannelController<Object?>(allowForeignErrors: false, sync: true);
    var channel = MultiChannel<Object?>(controller.local);

    var verboseChain = true;

    var printZone = hidePrints ? null : Zone.current;
    var spec = ZoneSpecification(print: (_, __, ___, line) {
      if (printZone != null) printZone.print(line);
      channel.sink.add({'type': 'print', 'line': line});
    });

    final suiteChannelManager = SuiteChannelManager();
    StackTraceFormatter().asCurrent(() {
      runZonedGuarded(() async {
        Function? main;
        try {
          main = getMain();
        } on NoSuchMethodError catch (_) {
          _sendLoadException(channel, 'No top-level main() function defined.');
          return;
        } catch (error, stackTrace) {
          _sendError(channel, error, stackTrace, verboseChain);
          return;
        }

        if (main is! Function()) {
          _sendLoadException(
              channel, 'Top-level main() function takes arguments.');
          return;
        }

        var queue = StreamQueue(channel.stream);
        var message = await queue.next as Map;
        assert(message['type'] == 'initial');

        queue.rest.cast<Map>().listen((message) {
          if (message['type'] == 'close') {
            controller.local.sink.close();
            return;
          }

          assert(message['type'] == 'suiteChannel');
          suiteChannelManager.connectIn(message['name'] as String,
              channel.virtualChannel(message['id'] as int));
        });

        if ((message['asciiGlyphs'] as bool?) ?? false) glyph.ascii = true;
        var metadata = Metadata.deserialize(message['metadata']);
        verboseChain = metadata.verboseTrace;
        var declarer = Declarer(
            metadata: metadata,
            platformVariables:
                Set.from(message['platformVariables'] as Iterable),
            collectTraces: message['collectTraces'] as bool,
            noRetry: message['noRetry'] as bool);
        StackTraceFormatter.current!.configure(
            except: _deserializeSet(message['foldTraceExcept'] as List),
            only: _deserializeSet(message['foldTraceOnly'] as List));

        if (beforeLoad != null) {
          await beforeLoad(suiteChannelManager.connectOut);
        }

        await declarer.declare(main);

        var suite = Suite(declarer.build(),
            SuitePlatform.deserialize(message['platform'] as Object),
            path: message['path'] as String);

        runZoned(() {
          Invoker.guard(
              () => RemoteListener._(suite, printZone)._listen(channel));
        },
            // Make the declarer visible to running tests so that they'll throw
            // useful errors when calling `test()` and `group()` within a test,
            // and so they can add to the declarer's `tearDownAll()` list.
            zoneValues: {#test.declarer: declarer});
      }, (error, stackTrace) {
        _sendError(channel, error, stackTrace, verboseChain);
      }, zoneSpecification: spec);
    });

    return controller.foreign;
  }

  /// Returns a [Set] from a JSON serialized list of strings, or `null` if the
  /// list is empty or `null`.
  static Set<String>? _deserializeSet(List? list) {
    if (list == null) return null;
    if (list.isEmpty) return null;
    return Set.from(list);
  }

  /// Sends a message over [channel] indicating that the tests failed to load.
  ///
  /// [message] should describe the failure.
  static void _sendLoadException(StreamChannel channel, String message) {
    channel.sink.add({'type': 'loadException', 'message': message});
  }

  /// Sends a message over [channel] indicating an error from user code.
  static void _sendError(StreamChannel channel, Object error,
      StackTrace stackTrace, bool verboseChain) {
    channel.sink.add({
      'type': 'error',
      'error': RemoteException.serialize(
          error,
          StackTraceFormatter.current!
              .formatStackTrace(stackTrace, verbose: verboseChain))
    });
  }

  RemoteListener._(this._suite, this._printZone);

  /// Send information about [_suite] across [channel] and start listening for
  /// commands to run the tests.
  void _listen(MultiChannel channel) {
    channel.sink.add({
      'type': 'success',
      'root': _serializeGroup(channel, _suite.group, [])
    });
  }

  /// Serializes [group] into a JSON-safe map.
  ///
  /// [parents] lists the groups that contain [group].
  Map _serializeGroup(
      MultiChannel channel, Group group, Iterable<Group> parents) {
    parents = parents.toList()..add(group);
    return {
      'type': 'group',
      'name': group.name,
      'metadata': group.metadata.serialize(),
      'trace': group.trace?.toString(),
      'setUpAll': _serializeTest(channel, group.setUpAll, parents),
      'tearDownAll': _serializeTest(channel, group.tearDownAll, parents),
      'entries': group.entries.map((entry) {
        return entry is Group
            ? _serializeGroup(channel, entry, parents)
            : _serializeTest(channel, entry as Test, parents);
      }).toList()
    };
  }

  /// Serializes [test] into a JSON-safe map.
  ///
  /// [groups] lists the groups that contain [test]. Returns `null` if [test]
  /// is `null`.
  Map? _serializeTest(
      MultiChannel channel, Test? test, Iterable<Group>? groups) {
    if (test == null) return null;

    var testChannel = channel.virtualChannel();
    testChannel.stream.listen((message) {
      assert(message['command'] == 'run');
      _runLiveTest(test.load(_suite, groups: groups),
          channel.virtualChannel(message['channel'] as int));
    });

    return {
      'type': 'test',
      'name': test.name,
      'metadata': test.metadata.serialize(),
      'trace': test.trace?.toString(),
      'channel': testChannel.id
    };
  }

  /// Runs [liveTest] and sends the results across [channel].
  void _runLiveTest(LiveTest liveTest, MultiChannel channel) {
    channel.stream.listen((message) {
      assert(message['command'] == 'close');
      liveTest.close();
    });

    liveTest.onStateChange.listen((state) {
      channel.sink.add({
        'type': 'state-change',
        'status': state.status.name,
        'result': state.result.name
      });
    });

    liveTest.onError.listen((asyncError) {
      channel.sink.add({
        'type': 'error',
        'error': RemoteException.serialize(
            asyncError.error,
            StackTraceFormatter.current!.formatStackTrace(asyncError.stackTrace,
                verbose: liveTest.test.metadata.verboseTrace))
      });
    });

    liveTest.onMessage.listen((message) {
      if (_printZone != null) _printZone!.print(message.text);
      channel.sink.add({
        'type': 'message',
        'message-type': message.type.name,
        'text': message.text
      });
    });

    runZoned(() {
      liveTest.run().then((_) => channel.sink.add({'type': 'complete'}));
    }, zoneValues: {#test.runner.test_channel: channel});
  }
}
