package de.ugoe.cs.eventbench.web;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import de.ugoe.cs.eventbench.web.data.WebEvent;

public class WeblogParser {
	
	private long timeout;
	
	private List<List<WebEvent>> sequences;
	
	public WeblogParser() {
		timeout = 3600000; // 1 hour session-timeout as default
	}
	
	public WeblogParser(long timeout) {
		this.timeout = timeout;
	}
	
	public List<List<WebEvent>> getSequences() {
		return sequences; 
	}
	
	public void parseFile(String filename) throws IOException, FileNotFoundException, ParseException {
		File f = new File(filename);
		FileReader reader = new FileReader(f);
		char[] buffer = new char[(int) f.length()];
		reader.read(buffer);
		reader.close();
		String[] lines = (new String(buffer)).split("\n");
		
		Map<String, List<Integer>> cookieSessionMap = new HashMap<String, List<Integer>>();
		int lastId = -1;
		
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		
		sequences = new ArrayList<List<WebEvent>>();
		
		for( String line : lines ) {
			String[] values = line.trim().split(" ");
			
			// use cookie as session identifier
			int cookieStart = values[0].lastIndexOf('.');
			String cookie = values[0].substring(cookieStart+1);
			String dateString = values[1].substring(1)+" "+values[2].substring(0, values[2].length()-1);
			long timestamp = dateFormat.parse(dateString).getTime();
			String uri = values[3];
			// String ref = values[4]; // referer is not yet used!
			List<String> postedVars = new ArrayList<String>();
			for( int i=5 ; i<values.length ; i++ ) {
				postedVars.add(values[i]);
			}
				
			WebEvent event = new WebEvent(uri, timestamp, postedVars);
			
			// find session and add event
			List<Integer> sessionIds = cookieSessionMap.get(cookie);
			if( sessionIds==null ) {
				sessionIds = new ArrayList<Integer>();
				// start new session
				sessionIds.add(++lastId);
				cookieSessionMap.put(cookie, sessionIds);
				sequences.add(new LinkedList<WebEvent>());
			} 
			Integer lastSessionIndex = sessionIds.get(sessionIds.size()-1);
			List<WebEvent> lastSession = sequences.get(lastSessionIndex);
			long lastEventTime = timestamp;
			if( !lastSession.isEmpty() ) {
				lastEventTime = lastSession.get(lastSession.size()-1).getTimestamp();
			}
			if( timestamp-lastEventTime>timeout ) {
				sessionIds.add(++lastId);
				List<WebEvent> newSession = new LinkedList<WebEvent>();
				newSession.add(event);
				sequences.add(newSession);
			} else {
				lastSession.add(event);
			}
		}
	}
}
