package de.hsadmin.core.qserv;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;

public class CommandShell {
	
	public static String execute(String command) throws ShellException {
		return execute(command, null);
	}

	public static String execute(String command, String stdInput) throws ShellException {
		Process backend = null;
		String callOutput = null;
		int exitCode = 0;
		try {
			String logCommand = command;
			if (stdInput != null)  {
				logCommand += "<<EOF\n" + stdInput + "EOF";
			}
			logCommand += "\n";
			// TODO logging
			System.out.println("--- shell command: ---");
			System.out.println(logCommand);

			String[] cmdArray = { "/bin/bash", "-c", command };
			backend = Runtime.getRuntime().exec(cmdArray);
			if (stdInput != null) {
				OutputStream stdInputStream = backend.getOutputStream();
				PrintWriter stdInputWriter = new PrintWriter(stdInputStream);
				stdInputWriter.print(stdInput);
				stdInputWriter.close();
				stdInputStream.close();
			}
			callOutput = readProcessStream(backend.getInputStream());
			exitCode = backend.waitFor();

			// TODO logging
			System.out.println("RET: " + exitCode);

			if (exitCode != 0) {
				String aErr = readProcessStream(backend.getErrorStream());

				// TODO logging
				System.out.println("ERR: " + aErr);
				System.out.println("--- done. ---");

				throw new ShellException(aErr);
			}

			// TODO logging
			System.out.println("--- done. ---");
		} catch (IOException e) {
			throw new ShellException(e);
		} catch (InterruptedException e) {
			throw new ShellException(e);
		}
		if (callOutput != null) {
			return callOutput.trim();
		}
		return null;
	}

	private static String readProcessStream(InputStream stream) throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
		StringBuffer textBuff = new StringBuffer();
		String textLine = reader.readLine();
		while (textLine != null) {
			textBuff.append(textLine);
			textBuff.append('\n');
			textLine = reader.readLine();
		}
		reader.close();
		return textBuff.toString();
	}
}
