package de.ugoe.cs.eventbench.web.commands;

import java.io.File;
import java.io.FileReader;
import java.security.InvalidParameterException;
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;
import de.ugoe.cs.util.console.Command;
import de.ugoe.cs.util.console.Console;

public class CMDloadSessionsFromClickstream implements Command {

	@Override
	public void run(List<Object> parameters) {
		// TODO Auto-generated method stub
		if( parameters.size() < 1 ) {
			throw new InvalidParameterException();
		}
		String source = (String) parameters.get(0);
		
		// TODO needs to be variable
		long timeout = 3600000; // 1 hour session-timeout
		
		try { // TODO dummy try/catch block
			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");
			
			Map<String, List<Integer>> cookieSessionMap = new HashMap<String, List<Integer>>();
			int lastId = -1;
			
			List<List<WebEvent>> sessions = new ArrayList<List<WebEvent>>();
			
			SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			
			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];
				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);
					sessions.add(new LinkedList<WebEvent>());
				} 
				Integer lastSessionIndex = sessionIds.get(sessionIds.size()-1);
				List<WebEvent> lastSession = sessions.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);
					sessions.add(newSession);
				} else {
					lastSession.add(event);
				}
			} 
			Console.traceln(sessions.toString());
		} catch(Exception e) {
			e.printStackTrace();
		}
		
	}
	
	@Override
	public void help() {
		// TODO Auto-generated method stub
		
	}

}
