package de.ugoe.cs.eventbench;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.List;

import de.ugoe.cs.eventbench.data.IReplayable;
import de.ugoe.cs.eventbench.data.ReplayableEvent;
import de.ugoe.cs.util.StringTools;
import de.ugoe.cs.util.console.Console;

public class ReplayGenerator {
	
	private IReplayDecorator decorator = null;
	
	int sessionId = 1;
	
	public void createLogfileMultipleSessions(List<List<ReplayableEvent<?>>> sequences, String filename) {
		OutputStreamWriter writer = openReplayFile(filename);
		if( writer!=null ) {		
			try {
				decorator = sequences.get(0).get(0).getReplayDecorator();
				if( decorator!=null ) {
					writer.write(decorator.getHeader());
				}
				for( List<ReplayableEvent<?>> actions : sequences ) {
					writeSession(actions, writer);
				}
				if( decorator!=null ) {
					writer.write(decorator.getFooter());
				}
				decorator = null;
				writer.close();
			} catch (IOException e) {
				Console.printerrln("Unable to write replay file " + filename);
			}
		}
	}
	
	public void createLogfileSingleSession(List<ReplayableEvent<?>> actions, String filename) {
		OutputStreamWriter writer = openReplayFile(filename);
		if( writer!=null ) {		
			try {
				actions.get(0).getReplayDecorator();
				if( decorator!=null ) {
					writer.write(decorator.getHeader());
				}
				writeSession(actions, writer);
				if( decorator!=null ) {
					writer.write(decorator.getFooter());
				}
				decorator = null;
				writer.close();
			} catch (IOException e) {
				Console.printerrln("Unable to write replay file " + filename);
			}
		}
	}

	private OutputStreamWriter openReplayFile(String filename) {
		File file = new File(filename);
		boolean fileCreated;
		try {
			fileCreated = file.createNewFile();
			if( !fileCreated ) {
				Console.traceln("Created logfile " + filename);
			} else {
				Console.traceln("Overwrote existing logfile " + filename);
			}
		} catch (IOException e) {
			Console.printerrln("Unable to create file " + filename);
			Console.printStacktrace(e);
		}
		OutputStreamWriter writer = null;
		try {
			writer = new OutputStreamWriter(new FileOutputStream(file), "UTF-16");
		} catch (IOException e) {
			Console.printerrln("Unable to open file for writing (read-only file):" + filename);
			Console.printStacktrace(e);
		}
		return writer;
	}
	
	private void writeSession(List<ReplayableEvent<?>> actions, OutputStreamWriter writer)
			throws IOException {
		if( decorator!=null ) {
			writer.write(decorator.getSessionHeader(sessionId));
		}
		for( ReplayableEvent<?> currentAction : actions ) {
			
			List<? extends IReplayable> replayables = currentAction.getReplayMessages();
			for( IReplayable replayble : replayables ) {
				writer.write(replayble.getReplay()+StringTools.ENDLINE);
				writer.flush();
			}
		}
		if( decorator!=null ) {
			writer.write(decorator.getSessionFooter(sessionId));
		}
		sessionId++;
	}

}
