package de.ugoe.cs.eventbench;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;

import org.apache.commons.codec.binary.Base64;

import de.ugoe.cs.util.StringTools;
import de.ugoe.cs.util.console.Console;

public class LogPreprocessor {
	
	private boolean sessionOpen = false;
	private boolean msgIncomplete = false;
	
	private boolean base64;
	
	public LogPreprocessor() {
		this(false);
	}
	
	public LogPreprocessor(boolean base64) {
		this.base64 = base64;
	}
	
	public void convertToXml(String source, String target) throws IOException, FileNotFoundException {
		OutputStreamWriter targetFile = new OutputStreamWriter(new FileOutputStream(target), "UTF-16");
		targetFile.write("<?xml version=\"1.0\" encoding=\"UTF-16\"?>" + StringTools.ENDLINE);
		targetFile.write("<log>" + StringTools.ENDLINE);
		processFile(source, targetFile);
		if( sessionOpen ) {
			targetFile.write(" </session>" + StringTools.ENDLINE);
		}
		targetFile.write("</log>");
		targetFile.close();
	}
	
	
	public void convertDirToXml(String path, String target) throws IOException, FileNotFoundException {
		OutputStreamWriter targetFile = new OutputStreamWriter(new FileOutputStream(target), "UTF-16");
		targetFile.write("<?xml version=\"1.0\" encoding=\"UTF-16\"?>" + StringTools.ENDLINE);
		targetFile.write("<log>" + StringTools.ENDLINE);
		File folder = new File(path);
		if( !folder.isDirectory() ) {
			throw new IOException(path + " is not a directory");
		}
		String absolutPath = folder.getAbsolutePath();
		for( String filename : folder.list() ) {
			String source = absolutPath + "/" + filename;
			Console.traceln("Processing file: " + source);
			processFile(source, targetFile);
		}
		
		if( sessionOpen ) {
			targetFile.write(" </session>" + StringTools.ENDLINE);
		}
		targetFile.write("</log>");
		targetFile.close();
	}

	private void processFile(String source, OutputStreamWriter targetFile)
			throws FileNotFoundException, IOException {
		File f = new File(source);
		FileReader reader = new FileReader(f);
		char[] buffer = new char[(int) f.length()];
		reader.read(buffer);
		reader.close();
		String[] lines = (new String(buffer)).split("\n");
		String incompleteLine = "";
		// Open source and read line by line
		for( String currentLine : lines ) {
			if( currentLine.contains("UL: <session>")) {
				if( sessionOpen) {
					targetFile.write(" </session>" + StringTools.ENDLINE);
					targetFile.write(" <session>" + StringTools.ENDLINE);
				} else {
					targetFile.write(" <session>" + StringTools.ENDLINE);
					sessionOpen = true;
				}
			} else if( currentLine.contains("UL: </session>")) {
				if( sessionOpen) {
					targetFile.write(" </session>" + StringTools.ENDLINE);
					sessionOpen = false;
				}
			} else if( msgIncomplete || currentLine.contains("UL: ")) {
				
				String currentContent;
				String actualLine;
				if( msgIncomplete ) {
					actualLine = currentLine;
				} else {
					String[] splitResult = currentLine.split("UL: ");
					actualLine = splitResult[1];
				}
				if( base64 ) {
					Base64 decoder = new Base64();
					byte[] decoded = decoder.decode(actualLine);
					currentContent = new String(decoded, "UTF-16LE");
					currentContent = currentContent.substring(0, currentContent.length()-1);
				} else {
					currentContent = actualLine;
				}
				if( msgIncomplete ) {
					incompleteLine += currentContent;
					if( incompleteLine.contains("</msg>") ) {
						msgIncomplete = false;
						targetFile.write(incompleteLine + StringTools.ENDLINE);
						incompleteLine = "";
					}
				} else {
					if( currentContent.contains("<msg") && sessionOpen ) {
						if( currentContent.contains("</msg>") ) {
							targetFile.write("  " + currentContent + StringTools.ENDLINE);
						} else {
							msgIncomplete = true;
							incompleteLine += currentContent;
						}
					}
				}
			}
		}
	}

}
