import static java.lang.System.err;
import static java.lang.System.out;
import java.io.*;
import java.util.*;

public class Sandbox {
	
	final static String
		pathLinux = "Tools\\Linux",
		pathWindows = "Tools\\Windows",
		pathMacOSX = "Tools\\MacOSX";

	public static void main(String[] args) {
		
		try {
			File log = new File("error.log");
			log.createNewFile();
			FileOutputStream os = new FileOutputStream(log);
			PrintStream ps = new PrintStream(os);
			System.setErr(ps);
		} catch (IOException e) {
			System.err.println("Error: Unable to create error log.");
		}
		
		switch (runipodpatcher()) {
			case -1:
				out.println("Sorry, host operating system not supported.");
				break;
			case 0:
				out.println("Error encountered. Unable to patch iPod.");
				break;
			case 1:
				out.println("iPod successfully patched.");
		}
		System.out.println("Fin!");
		

	}
	
	private static int runipodpatcher() {
		
		// ipodpatcher command
		String[] cmd = new String[3];
		
		// Arg 0 - ipodpatcher binary
		switch (getHost()) {
			case -1:
				return -1;
			case 00:
				return -1;
			case 11:
				cmd[0] = pathLinux + "\\ipodpatcher-32";
				break;
			case 12:
				cmd[0] = pathLinux + "\\ipodpatcher-64";
				break;
			case 13:
				cmd[0] = pathLinux + "\\ipodpatcher-ppc";
				break;
			case 21:
				cmd[0] = pathWindows + "\\ipodpatcher.exe";
				break;
			case 31:
				cmd[0] = pathMacOSX + "\\ipodpatcher.dmg";
				break;
			default: // Just in case
				err.println("Error: Unable to patch iPod.");
				return -1;
		}
		
		// Arg 1 - Add loader.bin
		cmd[1] = "--add-bootloader-bin";
		
		// Arg 2 - loader.bin file
		String loader = "Downloads\\Loader2\\loader.bin"; // For now
		cmd[2] = loader;
		
		// Execute
		try {
			Process ipodpatcher = Runtime.getRuntime().exec(cmd);
			

			// Get output

			Scanner ipodpatcherIn = new Scanner(ipodpatcher.getInputStream());
			Scanner ipodpatcherErr = new Scanner(ipodpatcher.getErrorStream());
			
			err.println("=================" +
						"\nipodpatcher error stream" +
						"\n=================");
			while (ipodpatcherErr.hasNext()) {
				err.println(ipodpatcherErr.nextLine());
			}
			err.println("=================\n");
			ipodpatcherErr.close();
			/*
			 * For some oddity, if the input stream is handled before the error stream,
			 * Java gets stuck. This is probably due to the inconsistencies in
			 * ipodpatcher's output of lines.
			 * (Sometimes [INFO] lines are printed to the normal output stream,
			 *  other times it is printed to the error stream).
			 */
			err.println("=================" +
						"\nipodpatcher output stream" +
						"\n=================");
			while (ipodpatcherIn.hasNext()) {
				err.println(ipodpatcherIn.nextLine());
			}
			ipodpatcherIn.close();
			err.println("=================\n");
			
			return 1;
			
		} catch (Exception e) {
			err.println("Error: Unable to run ipodpatcher binary.");
			return 0;
		}
	}
	
	
	/**
	 * Get properties of host computer. Used for calling ipodpatcher binary.
	 * @return
	 * 		-1 if unable to determine, <br>
	 *		00 if Unsupported, <br>
	 * 		11 if Linux (32-bit), <br>
	 * 		12 if Linux (64-bit), <br>
	 * 		13 if Linux (PPC), <br>
	 * 		21 if Windows, <br>
	 * 		31 if Mac OSX
	 */
	private static int getHost() {
		
		// Operating System
		String bufferOS = System.getProperty("os.name");
		
		// Undeterminable
		if (bufferOS == null) {
			err.println("Error: Unable to determine host operating system.");
			return -1;
		} else
	
		// Linux
		if (bufferOS.indexOf("Linux")!=-1) {
			// Architechture
			String bufferArch = System.getProperty("os.arch");
			if (bufferArch.indexOf("ppc")!=-1) {
				return 13;
			} else if (bufferArch.indexOf("64")!=-1) {
				return 12;
			} else if (bufferArch.indexOf("86")!=-1) {
				return 11;
			} else {
				return 11; // Hope will work
			}
		} else
			
		// Windows
		if (bufferOS.indexOf("Windows")!=-1) {
			return 21;
		} else
		
		// Mac OS X	
		if (bufferOS.indexOf("Mac OS X")!=-1) {
			return 31;
			
		// Unsupported
		} else {
			err.println("Error: Operating system not supported.");
			return 00;
		}
	}

}
