// Copyright (c) 2013, 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 'dart:convert';
import 'dart:io';

import 'package:webdriver/async_io.dart';

import 'android.dart';
import 'configuration.dart';
import 'path.dart';
import 'service/web_driver_service.dart';
import 'utils.dart';

typedef BrowserDoneCallback = void Function(BrowserTestOutput output);
typedef TestChangedCallback =
    void Function(String browserId, String output, int testId);
typedef NextTestCallback = BrowserTest? Function(String browserId);

class BrowserOutput {
  final StringBuffer stdout = StringBuffer();
  final StringBuffer stderr = StringBuffer();
  final StringBuffer eventLog = StringBuffer();
}

/// Class describing the interface for communicating with browsers.
abstract class Browser {
  static int _browserIdCounter = 1;
  static String _nextBrowserId() => "BROWSER${_browserIdCounter++}";

  /// Get the output that was written so far to stdout/stderr/eventLog.
  BrowserOutput get testBrowserOutput => _testBrowserOutput;
  BrowserOutput _testBrowserOutput = BrowserOutput();

  /// This is called after the process is closed, before the done future
  /// is completed.
  ///
  /// Subclasses can use this to cleanup any browser specific resources
  /// (temp directories, profiles, etc). The function is expected to do
  /// it's work synchronously.
  void Function()? _cleanup;

  /// The version of the browser - normally set when starting a browser
  Future<String> get version;

  /// The underlying process - don't mess directly with this if you don't
  /// know what you are doing (this is an interactive process that needs
  /// special treatment to not leak).
  Process? process;

  void Function(String)? logger;

  /// Id of the browser.
  final String id = _nextBrowserId();

  /// Reset the browser to a known configuration on start-up.
  /// Browser specific implementations are free to ignore this.
  static bool resetBrowserConfiguration = false;

  /// Print everything (stdout, stderr, usageLog) whenever we add to it
  bool debugPrint = false;

  /// This future returns when the process exits. It is also the return value
  /// of close()
  Future<bool>? done;

  Browser();

  static Browser fromConfiguration(TestConfiguration configuration) {
    Browser browser;
    switch (configuration.runtime) {
      case Runtime.firefox:
        browser = Firefox(configuration.browserLocation);
        break;
      case Runtime.chrome:
        browser = Chrome(
          configuration.browserLocation,
          noSandbox: configuration.noSandbox,
        );
        break;
      case Runtime.safari:
        var service = WebDriverService.fromRuntime(Runtime.safari);
        browser = Safari(service.port);
        break;
      default:
        throw "unreachable";
    }

    return browser;
  }

  static const List<String> supportedBrowsers = [
    'safari',
    'ff',
    'firefox',
    'chrome',
  ];

  static bool requiresFocus(String browserName) {
    return browserName == "safari";
  }

  // TODO(kustermann): add standard support for chrome on android
  static bool supportedBrowser(String name) {
    return supportedBrowsers.contains(name);
  }

  void _logEvent(String event) {
    var toLog = "$this ($id) - $event \n";
    if (debugPrint) print("usageLog: $toLog");
    logger?.call(toLog);

    _testBrowserOutput.eventLog.write(toLog);
  }

  void _addStdout(String output) {
    if (debugPrint) print("stdout: $output");

    _testBrowserOutput.stdout.write(output);
  }

  void _addStderr(String output) {
    if (debugPrint) print("stderr: $output");

    _testBrowserOutput.stderr.write(output);
  }

  Future<bool> close() {
    _logEvent("Close called on browser");
    if (process != null) {
      if (process!.kill(ProcessSignal.sigkill)) {
        _logEvent("Successfully sent kill signal to process.");
      } else {
        _logEvent("Sending kill signal failed.");
      }
      return done ?? Future.value(true);
    } else {
      _logEvent("The process is already dead.");
      return Future.value(true);
    }
  }

  /// Start the browser using the supplied argument.
  /// This sets up the error handling and usage logging.
  Future<bool> startBrowserProcess(
    String command,
    List<String> arguments, {
    Map<String, String>? environment,
  }) {
    return Process.start(command, arguments, environment: environment)
        .then((startedProcess) {
          _logEvent("Started browser using $command ${arguments.join(' ')}");
          process = startedProcess;
          // Used to notify when exiting, and as a return value on calls to
          // close().
          var doneCompleter = Completer<bool>();
          done = doneCompleter.future;

          var stdoutDone = Completer<void>();
          var stderrDone = Completer<void>();

          var stdoutIsDone = false;
          var stderrIsDone = false;
          StreamSubscription stdoutSubscription;
          StreamSubscription stderrSubscription;

          // This timer is used to close stdio to the subprocess once we got
          // the exitCode. Sometimes descendants of the subprocess keep stdio
          // handles alive even though the direct subprocess is dead.
          Timer? watchdogTimer;

          void closeStdout([_]) {
            if (!stdoutIsDone) {
              stdoutDone.complete();
              stdoutIsDone = true;

              if (stderrIsDone) {
                watchdogTimer?.cancel();
              }
            }
          }

          void closeStderr([_]) {
            if (!stderrIsDone) {
              stderrDone.complete();
              stderrIsDone = true;

              if (stdoutIsDone) {
                watchdogTimer?.cancel();
              }
            }
          }

          stdoutSubscription = process!.stdout
              .transform(utf8.decoder)
              .listen(
                _addStdout,
                onError: (error) {
                  // This should _never_ happen, but we really want this in the log
                  // if it actually does due to dart:io or vm bug.
                  _logEvent(
                    "An error occurred in the process stdout handling: $error",
                  );
                },
                onDone: closeStdout,
              );

          stderrSubscription = process!.stderr
              .transform(utf8.decoder)
              .listen(
                _addStderr,
                onError: (error) {
                  // This should _never_ happen, but we really want this in the log
                  // if it actually does due to dart:io or vm bug.
                  _logEvent(
                    "An error occurred in the process stderr handling: $error",
                  );
                },
                onDone: closeStderr,
              );

          process!.exitCode.then((exitCode) {
            _logEvent("Browser closed with exitcode $exitCode");

            if (!stdoutIsDone || !stderrIsDone) {
              watchdogTimer = Timer(maxStdioDelay, () {
                DebugLogger.warning(
                  "$maxStdioDelayPassedMessage (browser: $this)",
                );
                watchdogTimer = null;
                stdoutSubscription.cancel();
                stderrSubscription.cancel();
                closeStdout();
                closeStderr();
              });
            }

            Future.wait([stdoutDone.future, stderrDone.future])
                .then((_) {
                  process = null;
                  _cleanup?.call();
                })
                .catchError((error) {
                  _logEvent("Error closing browsers: $error");
                })
                .whenComplete(() => doneCompleter.complete(true));
          });
          return true;
        })
        .catchError((error) {
          _logEvent("Running $command $arguments failed with $error");
          return false;
        });
  }

  void resetTestBrowserOutput() {
    _testBrowserOutput = BrowserOutput();
  }

  /// Add useful info about the browser to the _testBrowserOutput.stdout,
  /// where it will be reported for failing tests.  Used to report which
  /// android device a failing test is running on.
  void logBrowserInfoToTestBrowserOutput() {}

  /// Starts the browser loading the given url
  Future<bool> start(String url);

  @override
  String toString() => '$runtimeType';
}

abstract class WebDriverBrowser extends Browser {
  WebDriver? _driver;
  final int _port;
  final Map<String, dynamic> _desiredCapabilities;
  bool _terminated = false;

  WebDriverBrowser(this._port, this._desiredCapabilities);

  @override
  Future<bool> start(String url) async {
    _logEvent('Starting $this browser on: $url');
    await _createDriver();
    if (_terminated) return false;
    await _driver!.get(url);
    try {
      _logEvent('Got version: ${await version}');
    } catch (error) {
      _logEvent('Failed to get version.\nError: $error');
      return false;
    }
    return true;
  }

  Future<void> _createDriver() async {
    for (var i = 5; i >= 0; i--) {
      // Give the driver process some time to be ready to accept connections.
      await Future.delayed(const Duration(seconds: 1));
      if (_terminated) return;
      try {
        _driver = await createDriver(
          uri: Uri.parse('http://localhost:$_port/'),
          desired: _desiredCapabilities,
        );
      } catch (error) {
        if (_terminated) return;
        if (i > 0) {
          _logEvent(
            'Failed to create driver ($i retries left).\nError: $error',
          );
        } else {
          _logEvent('Failed to create driver.\nError: $error');
          await close();
          rethrow;
        }
      }
      if (_driver != null) break;
    }
  }

  @override
  Future<bool> close() async {
    _terminated = true;
    await _driver?.quit();
    // Give the driver process some time to be quit the browser.
    return true;
  }
}

class Safari extends WebDriverBrowser {
  /// We get the safari version by parsing a version file
  static const versionFile = '/Applications/Safari.app/Contents/version.plist';

  Safari(int port) : super(port, {'browserName': 'safari'});

  @override
  Future<String> get version async {
    // Example of the file:
    // <?xml version="1.0" encoding="UTF-8"?>
    // <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    // <plist version="1.0">
    // <dict>
    // 	     <key>BuildVersion</key>
    // 	     <string>2</string>
    // 	     <key>CFBundleShortVersionString</key>
    // 	     <string>6.0.4</string>
    // 	     <key>CFBundleVersion</key>
    // 	     <string>8536.29.13</string>
    // 	     <key>ProjectName</key>
    // 	     <string>WebBrowser</string>
    // 	     <key>SourceVersion</key>
    // 	     <string>7536029013000000</string>
    // </dict>
    // </plist>
    final versionLine = (await File(versionFile).readAsLines())
        .skipWhile((line) => !line.contains("CFBundleShortVersionString"))
        .skip(1)
        .take(1);
    return versionLine.isEmpty ? 'unknown' : versionLine.first;
  }
}

class Chrome extends Browser {
  Chrome(this._binary, {this.noSandbox = false});

  final String _binary;
  final bool noSandbox;

  @override
  Future<String> get version async {
    if (Platform.isWindows) {
      // The version flag does not work on windows.
      // See issue:
      // https://code.google.com/p/chromium/issues/detail?id=158372
      // The registry hack does not seem to work.
      return "unknown on windows";
    }
    final result = await Process.run(_binary, ["--version"]);
    if (result.exitCode != 0) {
      _logEvent("Failed to get chrome version");
      _logEvent("Make sure $_binary is a valid program for running chrome");
      throw StateError(
        "Failed to get chrome version.\nExit code: ${result.exitCode}",
      );
    }
    return result.stdout as String;
  }

  @override
  Future<bool> start(String url) async {
    _logEvent("Starting chrome browser on: $url");
    if (!await File(_binary).exists()) {
      _logEvent("Chrome binary not available.");
      _logEvent("Make sure $_binary is a valid program for running chrome");
      return false;
    }
    try {
      _logEvent("Got version: ${await version}");
      final userDir = await Directory.systemTemp.createTemp();
      _cleanup = () {
        try {
          userDir.deleteSync(recursive: true);
        } catch (e) {
          _logEvent(
            "Error: failed to delete Chrome user-data-dir ${userDir.path}, "
            "will try again in 40 seconds: $e",
          );
          Timer(const Duration(seconds: 40), () {
            try {
              userDir.deleteSync(recursive: true);
            } catch (e) {
              _logEvent(
                "Error: failed on second attempt to delete Chrome "
                "user-data-dir ${userDir.path}: $e",
              );
            }
          });
        }
      };
      var args = [
        if (noSandbox) "--no-sandbox",
        "--bwsi",
        "--disable-component-update",
        "--disable-extensions",
        "--disable-popup-blocking",
        "--disable-features=IntensiveWakeUpThrottling",
        "--disable-blink-features=TimerThrottlingForBackgroundTabs",
        "--no-first-run",
        "--use-mock-keychain",
        "--password-store=basic",
        "--user-data-dir=${userDir.path}",
        url,
      ];

      // TODO(rnystrom): Uncomment this to open the dev tools tab when Chrome
      // is spawned. Handy for debugging tests.
      // args.add("--auto-open-devtools-for-tabs");

      return await startBrowserProcess(_binary, args);
    } catch (e) {
      _logEvent("Starting chrome failed with $e");
      return false;
    }
  }
}

class AndroidChrome extends Browser {
  static const String viewAction = 'android.intent.action.VIEW';
  static const String mainAction = 'android.intent.action.MAIN';
  static const String chromePackage = 'com.android.chrome';
  static const String chromeActivity = '.Main';
  static const String browserPackage = 'com.android.browser';
  static const String browserActivity = '.BrowserActivity';
  static const String firefoxPackage = 'org.mozilla.firefox';
  static const String firefoxActivity = '.App';
  static const String turnScreenOnPackage = 'com.google.dart.turnscreenon';
  static const String turnScreenOnActivity = '.Main';

  final AdbDevice _adbDevice;

  AndroidChrome(this._adbDevice);

  @override
  Future<bool> start(String url) {
    var chromeIntent = Intent(viewAction, chromePackage, chromeActivity, url);
    var turnScreenOnIntent = Intent(
      mainAction,
      turnScreenOnPackage,
      turnScreenOnActivity,
    );

    var testingResourcesDir = Path('third_party/android_testing_resources');
    if (!Directory(testingResourcesDir.toNativePath()).existsSync()) {
      DebugLogger.error("$testingResourcesDir doesn't exist. Exiting now.");
      exit(1);
    }

    var chromeAPK = testingResourcesDir.append('com.android.chrome-1.apk');
    var turnScreenOnAPK = testingResourcesDir.append('TurnScreenOn.apk');
    var chromeConfDir = testingResourcesDir.append('chrome_configuration');
    var chromeConfDirRemote = Path('/data/user/0/com.android.chrome/');

    return _adbDevice
        .waitForBootCompleted()
        .then((_) {
          return _adbDevice.forceStop(chromeIntent.package);
        })
        .then((_) {
          return _adbDevice.killAll();
        })
        .then((_) {
          return _adbDevice.adbRoot();
        })
        .then((_) {
          return _adbDevice.installApk(turnScreenOnAPK);
        })
        .then((_) {
          return _adbDevice.installApk(chromeAPK);
        })
        .then((_) {
          return _adbDevice.pushData(chromeConfDir, chromeConfDirRemote);
        })
        .then((_) {
          return _adbDevice.chmod('777', chromeConfDirRemote);
        })
        .then((_) {
          return _adbDevice.startActivity(turnScreenOnIntent).then((_) => true);
        })
        .then((_) {
          return _adbDevice.startActivity(chromeIntent).then((_) => true);
        });
  }

  @override
  Future<bool> close() async {
    await _adbDevice.forceStop(chromePackage);
    await _adbDevice.killAll();
    return true;
  }

  @override
  void logBrowserInfoToTestBrowserOutput() {
    _testBrowserOutput.stdout.write(
      'Android device id: ${_adbDevice.deviceId}\n',
    );
  }

  @override
  final Future<String> version = Future.value('unknown');

  @override
  String toString() => "chromeOnAndroid";
}

class Firefox extends Browser {
  Firefox(this._binary);

  final String _binary;

  static const String enablePopUp =
      'user_pref("dom.disable_open_during_load", false);';
  static const String disableDefaultCheck =
      'user_pref("browser.shell.checkDefaultBrowser", false);';
  static const String disableScriptTimeLimit =
      'user_pref("dom.max_script_run_time", 0);';
  static const String disableAutoUpdate =
      'user_pref("app.update.auto", false);';
  static const String skipTermsOfUse =
      'user_pref("termsofuse.bypassNotification", true);';

  void _createPreferenceFile(String path) {
    var file = File("$path/user.js");
    var randomFile = file.openSync(mode: FileMode.write);
    randomFile.writeStringSync(enablePopUp);
    randomFile.writeStringSync(disableDefaultCheck);
    randomFile.writeStringSync(disableScriptTimeLimit);
    randomFile.writeStringSync(disableAutoUpdate);
    randomFile.writeStringSync(skipTermsOfUse);
    randomFile.close();
  }

  @override
  Future<String> get version async {
    final result = await Process.run(_binary, ["--version"]);
    if (result.exitCode != 0) {
      _logEvent("Failed to get firefox version");
      _logEvent("Make sure $_binary is a valid program for running firefox");
      throw StateError(
        "Failed to get firefox version.\nExit code: ${result.exitCode}",
      );
    }
    return result.stdout as String;
  }

  @override
  Future<bool> start(String url) async {
    _logEvent("Starting firefox browser on: $url");
    try {
      _logEvent("Got version: ${await version}");
      final userDir = await Directory.systemTemp.createTemp();
      _createPreferenceFile(userDir.path);
      _cleanup = () {
        userDir.deleteSync(recursive: true);
      };
      var args = ["-profile", userDir.path, "-no-remote", "-new-instance", url];
      var environment = Map<String, String>.from(Platform.environment);
      environment["MOZ_CRASHREPORTER_DISABLE"] = "1";
      return await startBrowserProcess(_binary, args, environment: environment);
    } catch (e) {
      _logEvent("Starting firefox failed with $e");
      return false;
    }
  }
}

/// Describes the current state of a browser used for testing.
class BrowserStatus {
  Browser browser;
  BrowserTest? currentTest;

  // This is currently not used for anything except for error reporting.
  // Given the usefulness of this in debugging issues this should not be
  // removed even when we have a really stable system.
  BrowserTest? lastTest;
  bool timeout = false;
  Timer? nextTestTimeout;
  Stopwatch timeSinceRestart = Stopwatch()..start();

  BrowserStatus(this.browser);
}

/// Describes a single test to be run in the browser.
class BrowserTest {
  // TODO(ricow): Add timeout callback instead of the string passing hack.
  BrowserDoneCallback doneCallback;
  String url;
  int timeout;
  String lastKnownMessage = '';
  late Stopwatch stopwatch;

  Duration? delayUntilTestStarted;

  // We store this here for easy access when tests time out (instead of
  // capturing this in a closure)
  late Timer timeoutTimer;

  // Used for debugging, this is simply a unique identifier assigned to each
  // test.
  final int id = _idCounter++;
  static int _idCounter = 0;

  BrowserTest(this.url, this.doneCallback, this.timeout);

  String toJSON() => jsonEncode({'url': url, 'id': id});
}

/* Describes the output of running the test in a browser */
class BrowserTestOutput {
  final Duration? delayUntilTestStarted;
  final Duration duration;

  final String lastKnownMessage;

  final BrowserOutput browserOutput;
  final bool didTimeout;

  BrowserTestOutput(
    this.delayUntilTestStarted,
    this.duration,
    this.lastKnownMessage,
    this.browserOutput, {
    this.didTimeout = false,
  });
}

/// Encapsulates all the functionality for running tests in browsers.
/// Tests are added to the queue and the supplied callbacks are called
/// when a test completes.
/// BrowserTestRunner starts up to maxNumBrowser instances of the browser,
/// to run the tests, starting them sequentially, as needed, so only
/// one is starting up at a time.
/// BrowserTestRunner starts a BrowserTestingServer, which serves a
/// driver page to the browsers, serves tests, and receives results and
/// requests back from the browsers.
class BrowserTestRunner {
  static const int _maxNextTestTimeouts = 10;
  static const Duration _nextTestTimeout = Duration(seconds: 120);

  /// If the queue was recently empty, don't start another browser.
  static const Duration _minNonemptyQueueTime = Duration(seconds: 1);

  final TestConfiguration configuration;
  final BrowserTestingServer testingServer;
  final Browser Function(TestConfiguration configuration) browserFactory;

  final String localIp;
  final int maxNumBrowsers;
  int numBrowsers = 0;

  /// Used to send back logs from the browser (start, stop etc.).
  void Function(String)? logger;

  bool testingServerStarted = false;
  bool underTermination = false;
  int numBrowserGetTestTimeouts = 0;
  DateTime lastEmptyTestQueueTime = DateTime.now();
  String? _currentStartingBrowserId;
  List<BrowserTest> testQueue = [];
  Map<String, BrowserStatus> browserStatus = {};

  Map<String, AdbDevice> adbDeviceMapping = {};
  late List<AdbDevice> idleAdbDevices;

  /// This cache is used to guarantee that we never see double reporting.
  /// If we do we need to provide developers with this information.
  /// We don't add urls to the cache until we have run it.
  Map<int, String> testCache = {};

  Map<int, String> doubleReportingOutputs = {};
  List<String> timedOut = [];

  /// We will start a new browser when the test queue hasn't been empty
  /// recently, we have fewer than maxNumBrowsers browsers, and there is
  /// no other browser instance currently starting up.
  bool get queueWasEmptyRecently {
    return testQueue.isEmpty ||
        DateTime.now().difference(lastEmptyTestQueueTime) <
            _minNonemptyQueueTime;
  }

  /// While a browser is starting, but has not requested its first test, its
  /// browserId is stored in _currentStartingBrowserId.
  /// When no browser is currently starting, _currentStartingBrowserId is null.
  bool get aBrowserIsCurrentlyStarting => _currentStartingBrowserId != null;
  void markCurrentlyStarting(String id) {
    _currentStartingBrowserId = id;
  }

  void markNotCurrentlyStarting(String id) {
    if (_currentStartingBrowserId == id) _currentStartingBrowserId = null;
  }

  BrowserTestRunner(
    this.configuration,
    this.localIp,
    this.maxNumBrowsers, [
    this.browserFactory = Browser.fromConfiguration,
  ]) : testingServer = BrowserTestingServer(
         configuration,
         localIp,
         Browser.requiresFocus(configuration.runtime.name),
       ) {
    testingServer.testRunner = this;
  }

  Future<BrowserTestRunner> start() async {
    await testingServer.start();
    testingServer
      ..testDoneCallBack = handleResults
      ..testStatusUpdateCallBack = handleStatusUpdate
      ..testStartedCallBack = handleStarted
      ..nextTestCallBack = getNextTest;
    testingServerStarted = true;
    requestBrowser();
    return this;
  }

  /// requestBrowser() is called whenever we might want to start an additional
  /// browser instance.
  ///
  /// It is called when starting the BrowserTestRunner, and whenever a browser
  /// is killed, whenever a new test is enqueued, or whenever a browser
  /// finishes a test.
  /// So we are guaranteed that this will always eventually be called, as long
  /// as the test queue isn't empty.
  void requestBrowser() {
    if (!testingServerStarted) return;
    if (underTermination) return;
    if (numBrowsers == maxNumBrowsers) return;
    if (aBrowserIsCurrentlyStarting) return;
    if (numBrowsers > 0 && queueWasEmptyRecently) return;
    createBrowser();
  }

  Future<bool> createBrowser() {
    Browser browser;
    if (configuration.runtime == Runtime.chromeOnAndroid) {
      var device = idleAdbDevices.removeLast();
      browser = AndroidChrome(device);
      adbDeviceMapping[browser.id] = device;
    } else {
      browser = browserFactory(configuration);
      browser.logger = logger;
    }
    markCurrentlyStarting(browser.id);
    var status = BrowserStatus(browser);
    browserStatus[browser.id] = status;
    numBrowsers++;
    status.nextTestTimeout = createNextTestTimer(status);
    return browser.start(testingServer.getDriverUrl(browser.id));
  }

  void handleResults(String browserId, String output, int testId) {
    var status = browserStatus[browserId];
    if (testCache.containsKey(testId)) {
      doubleReportingOutputs[testId] = output;
      return;
    }

    var test = status?.currentTest;
    if (status == null || status.timeout) {
      // We don't do anything, this browser is currently being killed and
      // replaced. The browser here can be null if we decided to kill the
      // browser.
    } else if (test != null) {
      test.timeoutTimer.cancel();
      test.stopwatch.stop();

      if (test.id != testId) {
        print("Expected test id ${test.id} for ${test.url}");
        print("Got test id $testId");
        print("Last test id was ${status.lastTest?.id} for ${test.url}");
        throw "This should never happen, wrong test id";
      }
      testCache[testId] = test.url;

      // Report that the test is finished now
      var browserTestOutput = BrowserTestOutput(
        test.delayUntilTestStarted,
        test.stopwatch.elapsed,
        output,
        status.browser.testBrowserOutput,
      );
      test.doneCallback(browserTestOutput);

      status.lastTest = test;
      status.currentTest = null;
      status.nextTestTimeout = createNextTestTimer(status);
    } else {
      print("\nThis is bad, should never happen, handleResult no test");
      print("URL: ${status.lastTest?.url}");
      print(output);
      terminate().then((_) {
        exit(1);
      });
    }
  }

  void handleStatusUpdate(String browserId, String output, int testId) {
    var status = browserStatus[browserId];

    if (status == null || status.timeout) {
      // We don't do anything, this browser is currently being killed and
      // replaced. The browser here can be null if we decided to kill the
      // browser.
    } else if (status.currentTest?.id == testId) {
      status.currentTest!.lastKnownMessage = output;
    }
  }

  void handleStarted(String browserId, String output, int testId) {
    var status = browserStatus[browserId];
    if (status == null || status.timeout) return;

    var currentTest = status.currentTest;
    if (currentTest == null) return;

    currentTest.timeoutTimer.cancel();
    currentTest.timeoutTimer = createTimeoutTimer(currentTest, status);
    currentTest.delayUntilTestStarted = currentTest.stopwatch.elapsed;
  }

  Future handleTimeout(BrowserStatus status) async {
    // We simply kill the browser and starts up a new one!
    // We could be smarter here, but it does not seems like it is worth it.
    if (status.timeout) {
      DebugLogger.error("Got test timeout for an already restarting browser");
      return;
    }
    status.timeout = true;
    var currentTest = status.currentTest!;
    timedOut.add(currentTest.url);
    var id = status.browser.id;

    currentTest.stopwatch.stop();
    await status.browser.close();
    var lastKnownMessage =
        'Dom could not be fetched, since the test timed out.';
    if (currentTest.lastKnownMessage.isNotEmpty) {
      lastKnownMessage = currentTest.lastKnownMessage;
    }
    if (status.lastTest != null) {
      lastKnownMessage += '\nPrevious test was ${status.lastTest!.url}';
    }
    // Wait until the browser is closed before reporting the test as timeout.
    // This will enable us to capture stdout/stderr from the browser
    // (which might provide us with information about what went wrong).
    var browserTestOutput = BrowserTestOutput(
      currentTest.delayUntilTestStarted,
      currentTest.stopwatch.elapsed,
      lastKnownMessage,
      status.browser.testBrowserOutput,
      didTimeout: true,
    );
    currentTest.doneCallback(browserTestOutput);
    status.lastTest = status.currentTest;
    status.currentTest = null;

    // We don't want to start a new browser if we are terminating.
    if (underTermination) return;
    removeBrowser(id);
    requestBrowser();
  }

  /// Remove a browser that has closed from our data structures that track
  /// open browsers. Check if we want to replace it with a new browser.
  void removeBrowser(String id) {
    if (configuration.runtime == Runtime.chromeOnAndroid) {
      idleAdbDevices.add(adbDeviceMapping.remove(id)!);
    }
    markNotCurrentlyStarting(id);
    browserStatus.remove(id);
    --numBrowsers;
  }

  BrowserTest? getNextTest(String browserId) {
    markNotCurrentlyStarting(browserId);
    var status = browserStatus[browserId];
    if (status == null) return null;
    status.nextTestTimeout?.cancel();
    status.nextTestTimeout = null;
    if (testQueue.isEmpty) return null;

    // We are currently terminating this browser, don't start a new test.
    if (status.timeout) return null;

    var test = testQueue.removeLast();
    // If our queue isn't empty, try starting more browsers
    if (testQueue.isEmpty) {
      lastEmptyTestQueueTime = DateTime.now();
    } else {
      requestBrowser();
    }
    if (status.currentTest != null) {
      // TODO(ricow): Handle this better.
      print("Browser requested next test before reporting previous result");
      print("This happened for browser $browserId");
      print("Old test was: ${status.currentTest!.url}");
      print("The test before that was: ${status.lastTest?.url}");
      print("Timed out tests:");
      for (var v in timedOut) {
        print("  $v");
      }
      exit(1);
    }
    status.currentTest = test
      ..lastKnownMessage = ''
      ..timeoutTimer = createTimeoutTimer(test, status)
      ..stopwatch = (Stopwatch()..start());

    // Reset the test specific output information (stdout, stderr) on the
    // browser, since a new test is being started.
    status.browser.resetTestBrowserOutput();
    status.browser.logBrowserInfoToTestBrowserOutput();
    return test;
  }

  /// Creates a timer that is active while a test is running on a browser.
  Timer createTimeoutTimer(BrowserTest test, BrowserStatus status) {
    return Timer(Duration(seconds: test.timeout), () {
      handleTimeout(status);
    });
  }

  /// Creates a timer that is active while no test is running on the
  /// browser. It has finished one test, and it has not requested a new test.
  Timer createNextTestTimer(BrowserStatus status) {
    return Timer(BrowserTestRunner._nextTestTimeout, () {
      handleNextTestTimeout(status);
    });
  }

  void handleNextTestTimeout(BrowserStatus status) {
    DebugLogger.warning(
      "Browser timed out before getting next test. Restarting",
    );
    if (status.timeout) return;
    numBrowserGetTestTimeouts++;
    if (numBrowserGetTestTimeouts >= _maxNextTestTimeouts) {
      DebugLogger.error(
        "Too many browser timeouts before getting next test. Terminating",
      );
      terminate().then((_) => exit(1));
    } else {
      status.timeout = true;
      status.browser.close().then((_) {
        removeBrowser(status.browser.id);
        requestBrowser();
      });
    }
  }

  void enqueueTest(BrowserTest test) {
    testQueue.add(test);
    requestBrowser();
  }

  void printDoubleReportingTests() {
    if (doubleReportingOutputs.isEmpty) return;
    // TODO(ricow): die on double reporting.
    // Currently we just report this here, we could have a callback to the
    // encapsulating environment.
    print("");
    print("Double reporting tests");
    for (var id in doubleReportingOutputs.keys) {
      print("  ${testCache[id]}");
    }

    DebugLogger.warning("Double reporting tests:");
    for (var id in doubleReportingOutputs.keys) {
      DebugLogger.warning("${testCache[id]}");
    }
  }

  // TODO(26191): Call a unified fatalError(), that shuts down all subprocesses.
  // This just kills the browsers in this BrowserTestRunner instance.
  Future terminate() async {
    var browsers = <Browser>[];
    underTermination = true;
    testingServer.underTermination = true;
    for (var status in browserStatus.values) {
      browsers.add(status.browser);
      status.nextTestTimeout?.cancel();
      status.nextTestTimeout = null;
    }

    for (var browser in browsers) {
      await browser.close();
    }

    testingServer.errorReportingServer.close();
    printDoubleReportingTests();
  }
}

/// Interface of the testing server:
///
/// GET /driver/BROWSER_ID -- This will get the driver page to fetch
///                           and run tests ...
/// GET /next_test/BROWSER_ID -- returns "WAIT" "TERMINATE" or "url#id"
/// where url is the test to run, and id is the id of the test.
/// If there are currently no available tests the waitSignal is send
/// back. If we are in the process of terminating the terminateSignal
/// is send back and the browser will stop requesting new tasks.
/// POST /report/BROWSER_ID?id=NUM -- sends back the dom of the executed
///                                   test
class BrowserTestingServer {
  final TestConfiguration configuration;

  final String localIp;
  final bool requiresFocus;
  late BrowserTestRunner testRunner;

  static const String driverPath = "/driver";
  static const String nextTestPath = "/next_test";
  static const String reportPath = "/report";
  static const String statusUpdatePath = "/status_update";
  static const String startedPath = "/started";
  static const String waitSignal = "WAIT";
  static const String terminateSignal = "TERMINATE";

  var testCount = 0;
  late HttpServer errorReportingServer;
  bool underTermination = false;

  late TestChangedCallback testDoneCallBack;
  late TestChangedCallback testStatusUpdateCallBack;
  late TestChangedCallback testStartedCallBack;
  late NextTestCallback nextTestCallBack;

  BrowserTestingServer(this.configuration, this.localIp, this.requiresFocus);

  Future start() async {
    var server = await HttpServer.bind(
      localIp,
      configuration.testDriverErrorPort,
    );
    setupErrorServer(server);
    setupDispatchingServer(server);
  }

  void setupErrorServer(HttpServer server) {
    errorReportingServer = server;
    void errorReportingHandler(HttpRequest request) {
      var buffer = StringBuffer();
      request
          .cast<List<int>>()
          .transform(utf8.decoder)
          .listen(
            (data) {
              buffer.write(data);
            },
            onDone: () {
              var back = buffer.toString();
              request.response.headers.set("Access-Control-Allow-Origin", "*");
              request.response.done.catchError((error) {
                DebugLogger.error(
                  "Error getting error from browser"
                  "on uri ${request.uri.path}: $error",
                );
              });
              request.response.close();
              DebugLogger.error(
                "Error from browser on : "
                "${request.uri.path}, data:  $back",
              );
            },
            onError: print,
          );
    }

    void errorHandler(e) {
      if (!underTermination) print("Error occurred in httpserver: $e");
    }

    errorReportingServer.listen(errorReportingHandler, onError: errorHandler);
  }

  void setupDispatchingServer(HttpServer _) {
    var server = configuration.servers.server!;
    void noCache(HttpRequest request) {
      request.response.headers.set(
        "Cache-Control",
        "no-cache, no-store, must-revalidate",
      );
    }

    int testId(HttpRequest request) =>
        int.parse(request.uri.queryParameters["id"]!);
    String browserId(HttpRequest request, String prefix) =>
        request.uri.path.substring(prefix.length + 1);

    server.addHandler(reportPath, (HttpRequest request) {
      noCache(request);
      handleReport(
        request,
        browserId(request, reportPath),
        testId(request),
        isStatusUpdate: false,
      );
    });
    server.addHandler(statusUpdatePath, (HttpRequest request) {
      noCache(request);
      handleReport(
        request,
        browserId(request, statusUpdatePath),
        testId(request),
        isStatusUpdate: true,
      );
    });
    server.addHandler(startedPath, (HttpRequest request) {
      noCache(request);
      handleStarted(request, browserId(request, startedPath), testId(request));
    });

    void sendPageHandler(HttpRequest request) {
      // Do NOT make this method async. We need to call catchError below
      // synchronously to avoid unhandled asynchronous errors.
      noCache(request);
      Future<String> textResponse;
      if (request.uri.path.startsWith(driverPath)) {
        textResponse = getDriverPage(browserId(request, driverPath));
        request.response.headers.set('Content-Type', 'text/html');
      } else if (request.uri.path.startsWith(nextTestPath)) {
        textResponse = Future.value(
          getNextTest(browserId(request, nextTestPath)),
        );
        request.response.headers.set('Content-Type', 'text/plain');
      } else {
        textResponse = Future.value("");
      }
      request.response.done.catchError((error) async {
        if (!underTermination) {
          var text = await textResponse;
          print("URI ${request.uri}");
          print("text $text");
          throw "Error returning content to browser: $error";
        }
      });
      textResponse.then((String text) async {
        request.response.write(text);
        await request.listen(null).asFuture();
        // Ignoring the returned closure as it returns the 'done' future
        // which already has catchError installed above.
        request.response.close();
      });
    }

    server.addHandler(driverPath, sendPageHandler);
    server.addHandler(nextTestPath, sendPageHandler);
  }

  void handleReport(
    HttpRequest request,
    String browserId,
    int testId, {
    required bool isStatusUpdate,
  }) {
    var buffer = StringBuffer();
    request
        .cast<List<int>>()
        .transform(utf8.decoder)
        .listen(
          (data) {
            buffer.write(data);
          },
          onDone: () {
            var back = buffer.toString();
            request.response.close();
            if (isStatusUpdate) {
              testStatusUpdateCallBack(browserId, back, testId);
            } else {
              testDoneCallBack(browserId, back, testId);
            }
            // TODO(ricow): We should do something smart if we get an error here.
          },
          onError: (error) {
            DebugLogger.error("$error");
          },
        );
  }

  void handleStarted(HttpRequest request, String browserId, int testId) {
    var buffer = StringBuffer();
    // If an error occurs while receiving the data from the request stream,
    // we don't handle it specially. We can safely ignore it, since the started
    // events are not crucial.
    request
        .cast<List<int>>()
        .transform(utf8.decoder)
        .listen(
          (data) {
            buffer.write(data);
          },
          onDone: () {
            var back = buffer.toString();
            request.response.close();
            testStartedCallBack(browserId, back, testId);
          },
          onError: (error) {
            DebugLogger.error("$error");
          },
        );
  }

  String getNextTest(String browserId) {
    var nextTest = nextTestCallBack(browserId);
    if (underTermination) {
      // Browsers will be killed shortly, send them a terminate signal so
      // that they stop pulling.
      return terminateSignal;
    }
    return nextTest == null ? waitSignal : nextTest.toJSON();
  }

  String getDriverUrl(String browserId) {
    return "http://$localIp:${configuration.servers.port}/driver/$browserId";
  }

  Future<String> getDriverPage(String browserId) async {
    var errorReportingUrl =
        "http://$localIp:${errorReportingServer.port}/$browserId";
    var driverContent =
        """
<!DOCTYPE html><html>
<head>
  <title>Driving page</title>
  <meta charset="utf-8">
  <style>
.big-notice {
  background-color: red;
  color: white;
  font-weight: bold;
  font-size: xx-large;
  text-align: center;
}
.controller.box {
  white-space: nowrap;
  overflow: scroll;
  height: 6em;
}
body {
  font-family: sans-serif;
}
body div {
  padding-top: 10px;
}
  </style>
  <script type='text/javascript'>
    var STATUS_UPDATE_INTERVAL = 10000;

    function startTesting() {
      var number_of_tests = 0;
      var current_id;
      var next_id;

      // Has the test in the current iframe reported that it is done?
      var test_completed = true;
      // Has the test in the current iframe reported that it is started?
      var test_started = false;
      var testing_window;

      var embedded_iframe_div = document.getElementById('embedded_iframe_div');
      var embedded_iframe = document.getElementById('embedded_iframe');
      var number_div = document.getElementById('number');
      var executing_div = document.getElementById('currently_executing');
      var error_div = document.getElementById('unhandled_error');
      var start = new Date();

      function newTaskHandler() {
        if (this.readyState == this.DONE) {
          if (this.status == 200) {
            if (this.responseText == '$waitSignal') {
              setTimeout(getNextTask, 500);
            } else if (this.responseText == '$terminateSignal') {
              // Don't do anything, we will be killed shortly.
            } else {
              var elapsed = new Date() - start;
              var nextTask = JSON.parse(this.responseText);
              var url = nextTask.url;
              next_id = nextTask.id;
              run(url);
            }
          } else {
            reportError('Could not contact the server and get a new task');
          }
        }
      }

      function contactBrowserController(method,
                                        path,
                                        callback,
                                        msg,
                                        isUrlEncoded) {
        var client = new XMLHttpRequest();
        client.onreadystatechange = callback;
        client.open(method, path);
        if (isUrlEncoded) {
          client.setRequestHeader('Content-type',
                                  'application/x-www-form-urlencoded');
        }
        client.send(msg);
      }

      function getNextTask() {
        // Until we have the next task we set the current_id to a specific
        // negative value.
        contactBrowserController(
            'GET', '$nextTestPath/$browserId', newTaskHandler, "", false);
      }

      function childError(message, filename, lineno, colno, error) {
        sendStatusUpdate();
        if (error) {
          reportMessage('FAIL:' + filename + ':' + lineno +
               ':' + colno + ':' + message + '\\n' + error.stack, false, false);
        } else if (filename) {
          reportMessage('FAIL:' + filename + ':' + lineno +
               ':' + colno + ':' + message, false, false);
        } else {
          reportMessage('FAIL: ' + message, false, false);
        }
        return true;
      }

      function run(url) {
        number_of_tests++;
        number_div.textContent = number_of_tests;
        executing_div.textContent = url;
        if (typeof testing_window != 'undefined') {
          testing_window.close();
        }
        testing_window = window.open(url);
        test_started = false;
        test_completed = false;
      }

      window.onerror = function (message, url, lineNumber, columnNumber, err) {
        // Ensure the stack is included in the reported error, if available.
        if (err && err.stack) {
          message = message + '\\n' + err.stack;
        }
        if (url) {
          message = url + ':' + lineNumber + ':' + columnNumber + ':' + message;
        }
        reportError(message);
      }

      function reportError(msg) {
        function handleReady() {
          if (this.readyState == this.DONE && this.status != 200) {
            var error = 'Sending back error did not succeed: ' + this.status;
            error = error + '. Failed to send msg: ' + msg;
            error_div.innerHTML = error;
          }
        }
        contactBrowserController(
            'POST', '$errorReportingUrl?test=1', handleReady, msg, true);
      }

      function reportMessage(msg, isFirstMessage, isStatusUpdate) {
        if (isFirstMessage) {
          if (test_started) {
            reportMessage(
                "FAIL: test started more than once (test reloads itself) " +
                msg, false, false);
            return;
          }
          current_id = next_id;
          test_started = true;
          contactBrowserController(
            'POST', '$startedPath/$browserId?id=' + current_id,
            function () {}, msg, true);
        } else if (isStatusUpdate) {
            contactBrowserController(
              'POST', '$statusUpdatePath/$browserId?id=' + current_id,
              function() {}, msg, true);
        } else {
          var is_double_report = test_completed;
          var retry = 0;
          test_completed = true;

          function reportDoneMessage() {
            contactBrowserController(
                'POST', '$reportPath/$browserId?id=' + current_id,
                handleReady, msg, true);
          }

          function handleReady() {
            if (this.readyState == this.DONE) {
              if (this.status == 200) {
                if (!is_double_report) {
                  getNextTask();
                }
              } else {
                reportError('Error sending result to server. Status: ' +
                            this.status + ' Retry: ' + retry);
                retry++;
                if (retry < 3) {
                  setTimeout(reportDoneMessage, 1000);
                }
              }
            }
          }

          reportDoneMessage();
        }
      }

      function parseResult(result) {
        var parsedData = null;
        try {
          parsedData = JSON.parse(result);
        } catch(error) { }
        return parsedData;
      }

      // Browser tests send JSON messages to the driver window, handled here.
      function messageHandler(e) {
        var msg = e.data;
        if (typeof msg != 'string') return;
        if (e.source != testing_window) {
            reportError("Message received from old test window: " + msg);
            return;
        }
        var parsedData = parseResult(msg);
        if (parsedData) {
          // Only if the JSON message contains all required parameters,
          // will we handle it and post it back to the test controller.
          if ('message' in parsedData &&
              'is_first_message' in parsedData &&
              'is_status_update' in parsedData &&
              'is_done' in parsedData) {
            var message = parsedData['message'];
            var isFirstMessage = parsedData['is_first_message'];
            var isStatusUpdate = parsedData['is_status_update'];
            var isDone = parsedData['is_done'];
            if (!isFirstMessage && !isStatusUpdate) {
              if (!isDone) {
                alert("Bug in test_controller.js: " +
                      "isFirstMessage/isStatusUpdate/isDone were all false");
              }
            }
            reportMessage(message, isFirstMessage, isStatusUpdate);
          }
        }
      }

      function sendStatusUpdate () {
        var dom =
            embedded_iframe.contentWindow.document.documentElement.innerHTML;
        var message = 'Status:\\n';
        message += '  DOM:\\n' +
                   '    ' + dom;
        reportMessage(message, false, true);
      }

      function sendRepeatingStatusUpdate() {
        sendStatusUpdate();
        setTimeout(sendRepeatingStatusUpdate, STATUS_UPDATE_INTERVAL);
      }

      window.addEventListener('message', messageHandler, false);
      waitForDone = false;
      getNextTask();
    }
  </script>
</head>
  <body onload="startTesting()">

    <div class='big-notice'>
      Please keep this window in focus at all times.
    </div>

    <div>
      Some browsers, Safari, in particular, may pause JavaScript when not
      visible to conserve power consumption and CPU resources. In addition,
      some tests of focus events will not work correctly if this window doesn't
      have focus. It's also advisable to close any other programs that may open
      modal dialogs, for example, Chrome with Calendar open.
    </div>

    <div class="controller box">
    Dart test driver, number of tests: <span id="number"></span><br>
    Currently executing: <span id="currently_executing"></span><br>
    Unhandled error: <span id="unhandled_error"></span>
    </div>
    <div id="embedded_iframe_div" class="test box">
      <iframe id="embedded_iframe"></iframe>
    </div>
  </body>
</html>
""";
    return driverContent;
  }
}
