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

import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:path/path.dart' as p;
import 'package:test/test.dart';

import 'package:test_descriptor/test_descriptor.dart' as d;
import 'package:test_process/test_process.dart';

final throwsTestFailure = throwsA(TypeMatcher<TestFailure>());

void main() {
  group("shouldExit()", () {
    test("succeeds when the process exits with the given exit code", () async {
      var process = await startDartProcess('exitCode = 42;');
      expect(process.exitCode, completion(equals(42)));
      await process.shouldExit(greaterThan(12));
    });

    test("fails when the process exits with a different exit code", () async {
      var process = await startDartProcess('exitCode = 1;');
      expect(process.exitCode, completion(equals(1)));
      expect(process.shouldExit(greaterThan(12)), throwsTestFailure);
    });

    test("allows any exit code without an assertion", () async {
      var process = await startDartProcess('exitCode = 1;');
      expect(process.exitCode, completion(equals(1)));
      await process.shouldExit();
    });
  });

  group("kill() stops the process", () {
    test("parent", () async {
      var process = await startDartProcess('while (true);');

      // Should terminate.
      await process.kill();
    });

    test("child", () async {
      var childPath = p.join(d.sandbox, 'child.dart');
      File(childPath).writeAsStringSync('''
          void main() {
            while (true);
          }
        ''');

      var process = await startDartProcess('''
          var process = Process.start(${json.encode(childPath)});
          print(process.pid);
        ''');

      var pid = int.parse(await process.stdout.next);

      // Should terminate.
      await process.kill();

      expect(Process.killPid(pid), isFalse,
          reason: "Child process should no longer be running.");
    });
  });

  group("stdout and stderr", () {
    test("expose the process's standard io", () async {
      var process = await startDartProcess(r'''
        print("hello");
        stderr.writeln("hi");
        print("\nworld");
      ''');

      expect(process.stdout, emitsInOrder(['hello', '', 'world', emitsDone]));
      expect(process.stderr, emitsInOrder(['hi', emitsDone]));
      await process.shouldExit(0);
    });

    test("close when the process exits", () async {
      var process = await startDartProcess('');
      expect(expectLater(process.stdout, emits('hello')), throwsTestFailure);
      expect(expectLater(process.stderr, emits('world')), throwsTestFailure);
      await process.shouldExit(0);
    });
  });

  test("stdoutStream() and stderrStream() copy the process's standard io",
      () async {
    var process = await startDartProcess(r'''
      print("hello");
      stderr.writeln("hi");
      print("\nworld");
    ''');

    expect(process.stdoutStream(),
        emitsInOrder(['hello', '', 'world', emitsDone]));
    expect(process.stdoutStream(),
        emitsInOrder(['hello', '', 'world', emitsDone]));

    expect(process.stderrStream(), emitsInOrder(['hi', emitsDone]));
    expect(process.stderrStream(), emitsInOrder(['hi', emitsDone]));

    await process.shouldExit(0);

    expect(process.stdoutStream(),
        emitsInOrder(['hello', '', 'world', emitsDone]));
    expect(process.stderrStream(), emitsInOrder(['hi', emitsDone]));
  });

  test("stdin writes to the process", () async {
    var process = await startDartProcess(r'''
      stdinLines.listen((line) => print("> $line"));
    ''');

    process.stdin.writeln("hello");
    await expectLater(process.stdout, emits("> hello"));
    process.stdin.writeln("world");
    await expectLater(process.stdout, emits("> world"));
    await process.kill();
  });

  test("signal sends a signal to the process", () async {
    var process = await startDartProcess(r'''
      ProcessSignal.sighup.watch().listen((_) => print("HUP"));
      print("ready");
    ''');

    await expectLater(process.stdout, emits('ready'));
    process.signal(ProcessSignal.sighup);
    await expectLater(process.stdout, emits('HUP'));
    await process.kill();
  }, testOn: "!windows");
}

/// Starts a Dart process running [script] in a main method.
Future<TestProcess> startDartProcess(String script) {
  var dartPath = p.join(d.sandbox, 'test.dart');
  File(dartPath).writeAsStringSync('''
    import 'dart:async';
    import 'dart:convert';
    import 'dart:io';

    var stdinLines = stdin
        .transform(utf8.decoder)
        .transform(new LineSplitter());

    void main() {
      $script
    }
  ''');

  return TestProcess.start(Platform.executable, ['--enable-asserts', dartPath]);
}
