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