// Path: pre-alpha/pre-alpha1.1/grid/java/com/freeputer/io/piper/CircularPiper.java
// public class CircularPiper {
// 
//   private final Piper leftPiper;
//   private final Piper rightPiper;
//   private final Long waitNanos;
//   private final static long DEFAULT_WAIT_NANOS = 100000;
// 
//   public CircularPiper(Piper leftPiper, Piper rightPiper, Long waitNanos) {
//     this.leftPiper = leftPiper;
//     this.rightPiper = rightPiper;
//     if (waitNanos == null) {
//       this.waitNanos = DEFAULT_WAIT_NANOS;
//     } else {
//       this.waitNanos = waitNanos;
//     }
//   }
// 
//   public void run() {
//     int fromLeft;
//     int fromRight;
//     while (true) { // FIXME endless, needs FAILURE checks, needs close() calls
//       LockSupport.parkNanos(waitNanos);
//       if (leftPiper.avail() > 0) {
//         fromLeft = leftPiper.receive();
//         rightPiper.send(fromLeft);
//       }
//       if (rightPiper.avail() > 0) {
//         fromRight = rightPiper.receive();
//         leftPiper.send(fromRight);
//       }
//     }
//   }
// 
// }
// 
// Path: pre-alpha/pre-alpha1.1/grid/java/com/freeputer/io/piper/NativePiper.java
// public class NativePiper implements Piper {
// 
//   private final Process nativeProcess;
//   private final OutputStream sender;
//   private final InputStream receiver;
// 
//   public NativePiper(String... cmd) throws IOException {
// 
//     nativeProcess = new ProcessBuilder(cmd).start();
//     this.sender = new BufferedOutputStream(nativeProcess.getOutputStream(),
//         1024); // stdin of nativeProcess
//     this.receiver = new BufferedInputStream(nativeProcess.getInputStream(),
//         1024); // stdout of nativeProcess
//   }
// 
//   @Override
//   public int send(int outByte) { // TODO maybe delegate to StreamPiper
//     try {
//       sender.write(outByte);
//       sender.flush();
//       return Piper.SUCCESS;
//     } catch (IOException e) {
//       return Piper.FAILURE;
//     }
//   }
// 
//   @Override
//   public int receive() {
//     try {
//       final int result;
//       result = receiver.read();
//       return result;
//     } catch (IOException e) {
//       return Piper.FAILURE;
//     }
//   }
// 
//   @Override
//   public int avail() {
//     try {
//       final int avail;
//       avail = receiver.available();
//       return avail;
//     } catch (IOException e) {
//       return 0;
//     }
//   }
// 
//   @Override
//   public void close() {
//     // FIXME implement
//   }
// 
// }
// 
// Path: pre-alpha/pre-alpha1.1/grid/java/com/freeputer/io/piper/Piper.java
// public interface Piper {
// 
//   public static final int SUCCESS = 1;
//   public static final int FAILURE = -1;
// 
//   public int send(int c);
// 
//   public int receive();
// 
//   public int avail();
// 
//   public void close();
// 
// }
// 
// Path: pre-alpha/pre-alpha1.1/grid/java/com/freeputer/io/piper/ServerSocketPiper.java
// public class ServerSocketPiper implements Piper {
// 
//   private final ServerSocket serverSocket;
//   private final Socket clientSocket;
//   private final OutputStream serverToClient;
//   private final InputStream clientToServer;
// 
//   public ServerSocketPiper(int port) throws IOException {
//     serverSocket = new ServerSocket(port);
//     clientSocket = serverSocket.accept();
//     this.serverToClient = new BufferedOutputStream(
//         clientSocket.getOutputStream(), 1024);
//     this.clientToServer = new BufferedInputStream(
//         clientSocket.getInputStream(), 1024);
//   }
// 
//   @Override
//   public int send(int outByte) {
//     try {
//       serverToClient.write(outByte);
//       serverToClient.flush();
//       return Piper.SUCCESS;
//     } catch (IOException e) {
//       return Piper.FAILURE;
//     }
//   }
// 
//   @Override
//   public int receive() {
//     try {
//       final int result;
//       result = clientToServer.read();
//       return result;
//     } catch (IOException e) {
//       return Piper.FAILURE;
//     }
//   }
// 
//   @Override
//   public int avail() {
//     try {
//       final int avail;
//       avail = clientToServer.available();
//       return avail;
//     } catch (IOException e) {
//       return 0;
//     }
//   }
// 
//   @Override
//   public void close() {
//     // FIXME implement
//   }
// 
// }


import java.io.IOException;
import com.freeputer.io.piper.CircularPiper;
import com.freeputer.io.piper.NativePiper;
import com.freeputer.io.piper.Piper;
import com.freeputer.io.piper.ServerSocketPiper;
/*

Copyright © 2016, Robert Gollagher.
SPDX-License-Identifier: GPL-3.0+

License: GNU General Public License Version 3 or any later version
Author : Robert Gollagher  robert.gollagher@freeputer.net
Created: 20161228
Updated: 20161229
Version: pre-alpha-0.0.0.1

=========================================================================== */

package com.freeputer.io.util;



public class ServerEnsock {

  private final CircularPiper circle;

  public ServerEnsock(int port, String... cmd) throws IOException {
    Piper leftPiper = new ServerSocketPiper(port);
    Piper rightPiper = new NativePiper(cmd);
    circle = new CircularPiper(leftPiper, rightPiper, null);
  }

  public void run() {
    circle.run();
  }

  public static void main(String[] args) throws IOException {
    if (args.length != 2) {
// Path: pre-alpha/pre-alpha1.1/grid/java/com/freeputer/io/piper/CircularPiper.java
// public class CircularPiper {
// 
//   private final Piper leftPiper;
//   private final Piper rightPiper;
//   private final Long waitNanos;
//   private final static long DEFAULT_WAIT_NANOS = 100000;
// 
//   public CircularPiper(Piper leftPiper, Piper rightPiper, Long waitNanos) {
//     this.leftPiper = leftPiper;
//     this.rightPiper = rightPiper;
//     if (waitNanos == null) {
//       this.waitNanos = DEFAULT_WAIT_NANOS;
//     } else {
//       this.waitNanos = waitNanos;
//     }
//   }
// 
//   public void run() {
//     int fromLeft;
//     int fromRight;
//     while (true) { // FIXME endless, needs FAILURE checks, needs close() calls
//       LockSupport.parkNanos(waitNanos);
//       if (leftPiper.avail() > 0) {
//         fromLeft = leftPiper.receive();
//         rightPiper.send(fromLeft);
//       }
//       if (rightPiper.avail() > 0) {
//         fromRight = rightPiper.receive();
//         leftPiper.send(fromRight);
//       }
//     }
//   }
// 
// }
// 
// Path: pre-alpha/pre-alpha1.1/grid/java/com/freeputer/io/piper/NativePiper.java
// public class NativePiper implements Piper {
// 
//   private final Process nativeProcess;
//   private final OutputStream sender;
//   private final InputStream receiver;
// 
//   public NativePiper(String... cmd) throws IOException {
// 
//     nativeProcess = new ProcessBuilder(cmd).start();
//     this.sender = new BufferedOutputStream(nativeProcess.getOutputStream(),
//         1024); // stdin of nativeProcess
//     this.receiver = new BufferedInputStream(nativeProcess.getInputStream(),
//         1024); // stdout of nativeProcess
//   }
// 
//   @Override
//   public int send(int outByte) { // TODO maybe delegate to StreamPiper
//     try {
//       sender.write(outByte);
//       sender.flush();
//       return Piper.SUCCESS;
//     } catch (IOException e) {
//       return Piper.FAILURE;
//     }
//   }
// 
//   @Override
//   public int receive() {
//     try {
//       final int result;
//       result = receiver.read();
//       return result;
//     } catch (IOException e) {
//       return Piper.FAILURE;
//     }
//   }
// 
//   @Override
//   public int avail() {
//     try {
//       final int avail;
//       avail = receiver.available();
//       return avail;
//     } catch (IOException e) {
//       return 0;
//     }
//   }
// 
//   @Override
//   public void close() {
//     // FIXME implement
//   }
// 
// }
// 
// Path: pre-alpha/pre-alpha1.1/grid/java/com/freeputer/io/piper/Piper.java
// public interface Piper {
// 
//   public static final int SUCCESS = 1;
//   public static final int FAILURE = -1;
// 
//   public int send(int c);
// 
//   public int receive();
// 
//   public int avail();
// 
//   public void close();
// 
// }
// 
// Path: pre-alpha/pre-alpha1.1/grid/java/com/freeputer/io/piper/ServerSocketPiper.java
// public class ServerSocketPiper implements Piper {
// 
//   private final ServerSocket serverSocket;
//   private final Socket clientSocket;
//   private final OutputStream serverToClient;
//   private final InputStream clientToServer;
// 
//   public ServerSocketPiper(int port) throws IOException {
//     serverSocket = new ServerSocket(port);
//     clientSocket = serverSocket.accept();
//     this.serverToClient = new BufferedOutputStream(
//         clientSocket.getOutputStream(), 1024);
//     this.clientToServer = new BufferedInputStream(
//         clientSocket.getInputStream(), 1024);
//   }
// 
//   @Override
//   public int send(int outByte) {
//     try {
//       serverToClient.write(outByte);
//       serverToClient.flush();
//       return Piper.SUCCESS;
//     } catch (IOException e) {
//       return Piper.FAILURE;
//     }
//   }
// 
//   @Override
//   public int receive() {
//     try {
//       final int result;
//       result = clientToServer.read();
//       return result;
//     } catch (IOException e) {
//       return Piper.FAILURE;
//     }
//   }
// 
//   @Override
//   public int avail() {
//     try {
//       final int avail;
//       avail = clientToServer.available();
//       return avail;
//     } catch (IOException e) {
//       return 0;
//     }
//   }
// 
//   @Override
//   public void close() {
//     // FIXME implement
//   }
// 
// }


// Path: pre-alpha/pre-alpha1.1/grid/java/com/freeputer/io/util/ServerEnsock.java
import java.io.IOException;
import com.freeputer.io.piper.CircularPiper;
import com.freeputer.io.piper.NativePiper;
import com.freeputer.io.piper.Piper;
import com.freeputer.io.piper.ServerSocketPiper;

/*

Copyright © 2016, Robert Gollagher.
SPDX-License-Identifier: GPL-3.0+

License: GNU General Public License Version 3 or any later version
Author : Robert Gollagher  robert.gollagher@freeputer.net
Created: 20161228
Updated: 20161229
Version: pre-alpha-0.0.0.1

=========================================================================== */

package com.freeputer.io.util;



public class ServerEnsock {

  private final CircularPiper circle;

  public ServerEnsock(int port, String... cmd) throws IOException {
    Piper leftPiper = new ServerSocketPiper(port);
    Piper rightPiper = new NativePiper(cmd);
    circle = new CircularPiper(leftPiper, rightPiper, null);
  }

  public void run() {
    circle.run();
  }

  public static void main(String[] args) throws IOException {
    if (args.length != 2) {
      System.out.println("Must specify PORT COMMAND such as by:\n"