// Copyright (c) 2017, 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.

// @dart = 2.9

/// @assertion Stream<ProcessSignal> watch()
/// Watch for process signals.
/// The following ProcessSignals can be listened to:
/// - ProcessSignal.sighup.
/// - ProcessSignal.sigint. Signal sent by e.g. CTRL-C.
/// - ProcessSignal.sigterm. Not available on Windows.
/// - ProcessSignal.sigusr1. Not available on Windows.
/// - ProcessSignal.sigusr2. Not available on Windows.
/// - ProcessSignal.sigwinch. Not available on Windows.
///
/// Other signals are disallowed, as they may be used by the VM.
///
/// A signal can be watched multiple times, from multiple isolates, where all
/// callbacks are invoked when signaled, in no specific order.
///
/// @description Checks that mention ProcessSignals can be listened.
/// @author ngl@unipro.ru

import "dart:io";
import "dart:async";
import "../../../Utils/expect.dart";

check(ProcessSignal signal, int ec, [int ec2]) {
  String executable = Platform.resolvedExecutable;
  String eScript = Platform.script.toString();
  asyncStart();
  Process.start(executable, [
    ...Platform.executableArguments,
    eScript,
    signal.toString()
  ]).then((process) {
    process.stdin.close();
    process.stderr.drain();
    int dokill = 0;
    process.stdout.listen((out) {
      if (dokill < 2 ) {
        process.kill(signal);
        dokill++;
      }
    });
    process.exitCode.then((exitCode) {
      if (ec2 == null) {
      Expect.equals(ec, exitCode);
      } else {
        Expect.isTrue(
            exitCode == ec || exitCode == ec2, "exitCode is $exitCode");
      }
      asyncEnd();
    });
  });
}

runMain() {
  if (!Platform.isWindows) {
    check(ProcessSignal.sighup, -1);
    check(ProcessSignal.sigint, -2);
    check(ProcessSignal.sigterm, -15);
    check(ProcessSignal.sigusr1, -10, -30);
    check(ProcessSignal.sigusr2, -12, -31);
    // ProcessSignal.sigwinch does not kill process
    check(ProcessSignal.sigwinch, 0);
  }
}

runProcess(List<String> args) {
  // This process should die if it never receives a signal.
  var timeout = new Timer(new Duration(seconds: 5), () => exit(1));

  var sigCount = 0;
  var li1;
  bool sigw = false;

  void check() {
    if (sigCount > 1) {
      exit(1);
    }
    if (sigw && (sigCount == 1)) {
      exit(0);
    }
    if (sigCount == 1) {
      li1.cancel();
    }
    print("ready");
  }

  var signal;
  switch (args[0]) {
    case 'SIGHUP':
      signal = ProcessSignal.sighup;
      break;
    case 'SIGINT':
      signal = ProcessSignal.sigint;
      break;
    case 'SIGTERM':
      signal = ProcessSignal.sigterm;
      break;
    case 'SIGUSR1':
      signal = ProcessSignal.sigusr1;
      break;
    case 'SIGUSR2':
      signal = ProcessSignal.sigusr2;
      break;
    case 'SIGWINCH':
      signal = ProcessSignal.sigwinch;
      break;
  }

  li1 = signal.watch().listen((lsignal) {
    if (lsignal != signal) {
      exit(1);
    }
    sigCount++;
    if (signal == ProcessSignal.sigwinch) {
      sigw = true;
    }
    check();
  });

  check();
}

main(List<String> args) {
  if (args.length > 0)
    runProcess(args);
  else {
    runMain();
  }
}
