package org.builditbreakit.seada.logappend;

import java.io.IOException;

public class App {
	
	private static void applyCommand(String[] args, GalleryUpdateManager gum) throws IOException, SecurityException {
		// This line with throw if cmdline syntax is bad.
		AppendCommand cmd = new AppendCommand(args);
		
		// This line will throw if token is bad or logfile is corrupt/uncreatable.
		GalleryUpdate item = gum.getGalleryFor(cmd);
		
		// This switch statement should throw if a guest name is used as an employee name,
		// a timestamp isn't >= previous value, etc.
		switch (cmd.getEvent()) {
		case ARRIVAL:
			if (cmd.getRoom() == -1) {
				item.state.arriveAtBuilding(cmd.getTimestamp(), cmd.getVisitorName(), cmd.getVisitorType());
			} else {
				item.state.arriveAtRoom(cmd.getTimestamp(), cmd.getVisitorName(), cmd.getVisitorType(), cmd.getRoom());
			}
			break;
		case DEPARTURE:
			if (cmd.getRoom() == -1) {
				item.state.departBuilding(cmd.getTimestamp(), cmd.getVisitorName(), cmd.getVisitorType());
			} else {
				item.state.departRoom(cmd.getTimestamp(), cmd.getVisitorName(), cmd.getVisitorType(), cmd.getRoom());
			}
			break;
		default:
			throw new IllegalArgumentException("bad event type (neither arrival nor departure)");
		}
		
		item.modified = true;
	}
	
	/**
	 * @return Number of commands that modified model.
	 */
	private static void processBatch(GalleryUpdateManager gum, String batchFilePath) throws IOException {
		
		BatchProcessor b = new BatchProcessor(batchFilePath);
		while (b.hasNextLine()) {
			try {
				applyCommand(b.nextLine(), gum);
			} catch (SecurityException e) {
				System.out.println("integrity violation");
			} catch (Throwable e) {
				System.out.println("invalid");
			}
		}
	}
	
	public static void main(String[] args) {
		int exitCodeForErrors = 255;
		try {
			
			GalleryUpdateManager gum = new GalleryUpdateManager();
			
			if (args.length == 2 && args[0].equals("-B")) {
				exitCodeForErrors = 0;
				processBatch(gum, args[1]);
				
			} else {
				applyCommand(args, gum);
			}
			
			gum.save();
			System.exit(0);
			
		} catch (SecurityException e) {
			System.out.println("integrity violation");
			System.exit(exitCodeForErrors);
		} catch (Throwable e) {
			System.out.println("invalid");
			System.exit(exitCodeForErrors);
		}
	}
}

@@ -53,27 +53,109 @@
 java.io.
-IOException
+File;%0Aimport java.io.FileOutputStream;%0Aimport java.io.IOException;%0Aimport java.io.PrintWriter
 ;%0A%0Apubli
@@ -1616,16 +1616,49 @@
 ne()) %7B%0A
+%09%09%09String%5B%5D args = b.nextLine();%0A
 %09%09%09try %7B
@@ -1675,28 +1675,20 @@
 Command(
-b.nextLine()
+args
 , gum);%0A
@@ -1718,24 +1718,47 @@
 eption e) %7B%0A
+%09%09%09%09logError(e, args);%0A
 %09%09%09%09System.o
@@ -1815,24 +1815,47 @@
 owable e) %7B%0A
+%09%09%09%09logError(e, args);%0A
 %09%09%09%09System.o
@@ -1891,16 +1891,524 @@
 %09%7D%0A%09%7D%0A%09%0A
+%09private static final boolean PRINT_ERRORS = true; // disable before final build%0A%09%0A%09private static void logError(Throwable e, String%5B%5D args) %7B%0A%09%09try %7B%0A%09%09%09File tempFile = File.createTempFile(%22seada-logappend%22, %22tmp%22);%0A%09%09%09FileOutputStream fout = new FileOutputStream(tempFile);%0A%09%09%09PrintWriter out = new PrintWriter(fout);%0A%09%09%09out.print(%22Error with%22);%0A%09%09%09for (String arg: args) %7B%0A%09%09%09%09out.print(' ');%0A%09%09%09%09out.print(arg);%0A%09%09%09%7D%0A%09%09%09out.println(%22%5Cn%22);%0A%09%09%09e.printStackTrace(out);%0A%09%09%7D catch (IOException e1) %7B%0A%09%09%7D%0A%09%7D%0A%09%0A
 %09public 
@@ -2779,24 +2779,46 @@
 eption e) %7B%0A
+%09%09%09logError(e, args);%0A
 %09%09%09System.ou
@@ -2886,16 +2886,16 @@
 rrors);%0A
-
 %09%09%7D catc
@@ -2908,24 +2908,46 @@
 owable e) %7B%0A
+%09%09%09logError(e, args);%0A
 %09%09%09System.ou

Make logappend temporarily write errors to a file that will help us diagnose problems