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

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

import 'package:stack_trace/stack_trace.dart';
import 'package:typed_data/typed_buffers.dart';

class BrowserProcess {
  /// Creates a new browser.
  ///
  /// Clients pass in [startBrowser], which asynchronously returns the browser
  /// process. Any errors in [startBrowser] (even those raised asynchronously
  /// after it returns) are piped to [onExit] and will cause the browser to be
  /// killed.
  BrowserProcess(Future<Process> Function() startBrowser) {
    // Don't return a Future here because there's no need for the caller to wait
    // for the process to actually start. They should just wait for the HTTP
    // request instead.
    runZonedGuarded(() async {
      final Process process = await startBrowser();
      _processCompleter.complete(process);

      final Uint8Buffer output = Uint8Buffer();
      void drainOutput(Stream<List<int>> stream) {
        try {
          _ioSubscriptions
              .add(stream.listen(output.addAll, cancelOnError: true));
        } on StateError catch (_) {}
      }

      // If we don't drain the stdout and stderr the process can hang.
      drainOutput(process.stdout);
      drainOutput(process.stderr);

      final int exitCode = await process.exitCode;

      // This hack dodges an otherwise intractable race condition. When the user
      // presses Control-C, the signal is sent to the browser and the test
      // runner at the same time. It's possible for the browser to exit before
      // the [Browser.close] is called, which would trigger the error below.
      //
      // A negative exit code signals that the process exited due to a signal.
      // However, it's possible that this signal didn't come from the user's
      // Control-C, in which case we do want to throw the error. The only way to
      // resolve the ambiguity is to wait a brief amount of time and see if this
      // browser is actually closed.
      if (!_closed && exitCode < 0) {
        await Future<void>.delayed(const Duration(milliseconds: 200));
      }

      if (!_closed && exitCode != 0) {
        final String outputString = utf8.decode(output);
        String message = 'Browser process failed with exit code $exitCode.';
        if (outputString.isNotEmpty) {
          message += '\nStandard output:\n$outputString';
        }

        throw Exception(message);
      }

      _onExitCompleter.complete();
    }, (dynamic error, StackTrace? stackTrace) {
      // Ignore any errors after the browser has been closed.
      if (_closed) {
        return;
      }

      // Make sure the process dies even if the error wasn't fatal.
      _process.then((Process process) => process.kill());

      stackTrace ??= Trace.current();

      if (_onExitCompleter.isCompleted) {
        return;
      }
      _onExitCompleter.completeError(
        Exception('Failed to run browser process: $error.'),
        stackTrace,
      );
    });
  }

  /// The underlying process.
  ///
  /// This will fire once the process has started successfully.
  Future<Process> get _process => _processCompleter.future;
  final Completer<Process> _processCompleter = Completer<Process>();

  /// Whether [close] has been called.
  bool _closed = false;

  /// A future that completes when the browser exits.
  ///
  /// If there's a problem starting or running the browser, this will complete
  /// with an error.
  Future<void> get onExit => _onExitCompleter.future;
  final Completer<void> _onExitCompleter = Completer<void>();

  /// Standard IO streams for the underlying browser process.
  final List<StreamSubscription<void>> _ioSubscriptions = <StreamSubscription<void>>[];

  /// Kills the browser process.
  ///
  /// Returns the same [Future] as [onExit], except that it won't emit
  /// exceptions.
  Future<void> close() async {
    _closed = true;

    // If we don't manually close the stream the test runner can hang.
    // For example this happens with Chrome Headless.
    // See SDK issue: https://github.com/dart-lang/sdk/issues/31264
    for (final StreamSubscription<void> stream in _ioSubscriptions) {
      unawaited(stream.cancel());
    }

    (await _process).kill();

    // Swallow exceptions. The user should explicitly use [onExit] for these.
    return onExit.catchError((dynamic _) {});
  }
}
