/*
 *
 * Copyright (c) 2010 by Joel Uckelman
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License (LGPL) as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, copies are available
 * at http://www.opensource.org.
 */

package VASSAL.tools.io;

import VASSAL.Info;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.concurrent.CancellationException;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

import org.junit.Test;

import static org.junit.Assert.*;

public class ProcessCallableTest {

  @Test
  public void testNormal() throws Exception {
    final byte[] eout = "Jackdaws love my big sphinx of quartz.\n".getBytes();
    final byte[] eerr = "Veldt jynx grimps waqf zho buck.\n".getBytes();

    final ProcessBuilder pb = new ProcessBuilder(
      Info.javaBinPath,
      "-cp",
      System.getProperty("java.class.path"),
      "VASSAL.tools.io.ProcessCallableTestEchoer"
    );

    final Process proc = pb.start();

    final ByteArrayOutputStream out = new ByteArrayOutputStream();
    final ByteArrayOutputStream err = new ByteArrayOutputStream();

    final ExecutorService exec = Executors.newCachedThreadPool();

    final InputOutputStreamPump outPump = new InputOutputStreamPump(null, out);
    final InputOutputStreamPump errPump = new InputOutputStreamPump(null, err);

    final ProcessCallable c = new ProcessCallable(proc, outPump, errPump, exec);
    final Future<Integer> f = exec.submit(c);

    final OutputStream pin = proc.getOutputStream();

    pin.write(eout);
    pin.write(eerr);
    pin.write("42\n".getBytes());
    pin.close();

    assertEquals(42, (int) f.get());
    assertArrayEquals(eout, out.toByteArray());
    assertArrayEquals(eerr, err.toByteArray());
  }

  @Test
  public void testInterrupt() throws Exception {
    final ProcessBuilder pb = new ProcessBuilder(
      "java",
      "-cp",
      System.getProperty("java.class.path"),
      "VASSAL.tools.io.ProcessCallableTestBlocker"
    );

    final Process proc = pb.start();

    final ByteArrayOutputStream out = new ByteArrayOutputStream();
    final ByteArrayOutputStream err = new ByteArrayOutputStream();

    final ExecutorService exec = Executors.newCachedThreadPool();

    final InputOutputStreamPump outPump = new InputOutputStreamPump(null, out);
    final InputOutputStreamPump errPump = new InputOutputStreamPump(null, err);

    final ProcessCallable c = new ProcessCallable(proc, outPump, errPump, exec);
    final Future<Integer> f = exec.submit(c);

    f.cancel(true);

    try {
      f.get();
      fail();
    }
    catch (CancellationException e) {
      // expected
    }

    assertArrayEquals(new byte[0], out.toByteArray());
    assertArrayEquals(new byte[0], err.toByteArray());
  }
}

@@ -1128,32 +1128,80 @@
 ows Exception %7B%0A
+    final String EOL = System.lineSeparator();%0A%0A
     final byte%5B%5D
@@ -1208,16 +1208,17 @@
  eout = 
+(
 %22Jackdaw
@@ -1248,19 +1248,24 @@
  quartz.
-%5Cn%22
+%22 + EOL)
 .getByte
@@ -1293,16 +1293,17 @@
  eerr = 
+(
 %22Veldt j
@@ -1327,19 +1327,24 @@
 ho buck.
-%5Cn%22
+%22 + EOL)
 .getByte
@@ -2182,14 +2182,20 @@
 ite(
+(
 %2242
-%5Cn%22
+%22 + EOL)
 .get

Use System.lineSeparator() in ProcessCallableTest, which fails on Windows due to String "\n" not being translated to "\r\n" on Windows.