// 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)
            ..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)
            ..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(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,
  ]);
}
