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

// OtherResources=signal_test_script.dart
// OtherResources=signals_test_script.dart

import "dart:io";
import "dart:convert";

import "package:expect/expect.dart";
import "package:async_helper/async_helper.dart";

void testSignals(int usr1Expect, int usr2Expect,
    [int? usr1Send, int? usr2Send, bool shouldFail = false]) {
  if (usr1Send == null) usr1Send = usr1Expect;
  if (usr2Send == null) usr2Send = usr2Expect;
  asyncStart();
  Process.start(
          Platform.executable,
          []
            ..addAll(Platform.executableArguments)
            ..add('--verbosity=warning')
            ..addAll([
              Platform.script.resolve('signals_test_script.dart').toFilePath(),
              usr1Expect.toString(),
              usr2Expect.toString()
            ]))
      .then((process) {
    process.stdin.close();
    process.stderr.drain();
    int v = 0;
    process.stdout.listen((out) {
      // Send as many signals as 'ready\n' received on stdout
      int count = out.where((c) => c == '\n'.codeUnitAt(0)).length;
      for (int i = 0; i < count; i++) {
        if (v < usr1Send!) {
          process.kill(ProcessSignal.sigusr1);
        } else if (v < usr1Send + usr2Send!) {
          process.kill(ProcessSignal.sigusr2);
        }
        v++;
      }
    });
    process.exitCode.then((exitCode) {
      Expect.equals(shouldFail, exitCode != 0);
      asyncEnd();
    });
  });
}

void testSignal(ProcessSignal signal) {
  asyncStart();
  Process.start(
          Platform.executable,
          []
            ..addAll(Platform.executableArguments)
            ..add('--verbosity=warning')
            ..addAll([
              Platform.script.resolve('signal_test_script.dart').toFilePath(),
              signal.toString()
            ]))
      .then((process) {
    process.stdin.close();
    process.stderr.drain();

    var output = "";
    process.stdout.transform(utf8.decoder).listen((str) {
      output += str;
      if (output == 'ready\n') {
        process.kill(signal);
      }
    }, onDone: () {
      Expect.equals('ready\n$signal\n', output);
    });
    process.exitCode.then((exitCode) {
      Expect.equals(0, exitCode);
      asyncEnd();
    });
  });
}

void testMultipleSignals(List<ProcessSignal> signals) {
  for (var signal in signals) {
    asyncStart();
    Process.start(
            Platform.executable,
            []
              ..addAll(Platform.executableArguments)
              ..add('--verbosity=warning')
              ..add(Platform.script
                  .resolve('signal_test_script.dart')
                  .toFilePath())
              ..addAll(signals.map((s) => s.toString())))
        .then((process) {
      process.stdin.close();
      process.stderr.drain();

      var output = "";
      process.stdout.transform(utf8.decoder).listen((str) {
        output += str;
        if (output == 'ready\n') {
          process.kill(signal);
        }
      }, onDone: () {
        Expect.equals('ready\n$signal\n', output);
      });
      process.exitCode.then((exitCode) {
        Expect.equals(0, exitCode);
        asyncEnd();
      });
    });
  }
}

void testListenCancel() {
  for (int i = 0; i < 10; i++) {
    ProcessSignal.sigint.watch().listen(null).cancel();
  }
}

void main() {
  testListenCancel();
  if (Platform.isWindows) return;
  testSignals(0, 0);
  testSignals(1, 0);
  testSignals(0, 1);
  testSignals(1, 1);
  testSignals(10, 10);
  testSignals(10, 1);
  testSignals(1, 10);
  testSignals(1, 0, 0, 1, true);
  testSignals(0, 1, 1, 0, true);

  testSignal(ProcessSignal.sighup);
  testSignal(ProcessSignal.sigint);
  testSignal(ProcessSignal.sigterm);
  testSignal(ProcessSignal.sigusr1);
  testSignal(ProcessSignal.sigusr2);
  testSignal(ProcessSignal.sigwinch);

  testMultipleSignals([
    ProcessSignal.sighup,
    ProcessSignal.sigint,
    ProcessSignal.sigterm,
    ProcessSignal.sigusr1,
    ProcessSignal.sigusr2,
    ProcessSignal.sigwinch,
  ]);
}
