package uy.edu.udelar.forrest.forrestloganalyser.app;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import uy.edu.udelar.forrest.forrestloganalyser.exceptions.ProcesarIndicadoresException;
import uy.edu.udelar.forrest.forrestloganalyser.model.MainModel;

public class CargarCubos {

	public CargarCubos(){
		
	}
	
	public void procesar(){
		cargarDimAcciones("1","acciones_clearball");
		cargarDimAcciones("2","acciones_dribble");
		cargarDimAcciones("3","acciones_intercept");
		cargarDimAcciones("4","acciones_moveposest");
		cargarDimAcciones("5","acciones_moveto");
		cargarDimAcciones("7","acciones_score");
		cargarDimAccionesPass();
		cargarIndicadores();
	}
	
	private void cargarDimAccionesPass(){
		String sqlSentence = "";
	    Statement stmt, stmt2;
	    String id_partido = "", ciclo = "", nro_agente = "";
	    String dim_tiempo = "", dim_acciones = "", dim_pospelota = "";
	    double posx = 0, posy = 0;
	    int agente_receptor = 0;
	    int cant_pases = 0, cant_pases_ok = 0, cant_pases_nok = 0, cant_pases_ok_coord = 0;
	    ResultSet rs, rs2;
	    Connection connection = MainModel.getDataBase().getConnection();
	    try{
	        sqlSentence = "Select * from acciones_passto where id_partido = "+
	                       MainModel.getIdPartido();
	        MainModel.getLogger().logDebug("CargarCubos::procesar - Voy a ejecutar la sentencia: "+
	        		                        sqlSentence);
	        stmt = connection.createStatement();
	        rs = stmt.executeQuery(sqlSentence);
	        //dim_acciones
	        dim_acciones = "6";
	        while (rs.next()){
	        	//Calculo la dim_tiempo
	        	ciclo = rs.getString("ciclo");
	        	sqlSentence = "Select identificador from dim_tiempo where ciclo="+ciclo;
		        stmt2 = connection.createStatement();
		        rs2 = stmt2.executeQuery(sqlSentence);
		        while (rs2.next()){
		        	dim_tiempo = rs2.getString("identificador");
		        }
		        rs2.close();
		        stmt2.close();
	        	
		        //Calculo la dim_partidos
	        	id_partido = rs.getString("id_partido");

	        	//Calculo la dim_pospelota
	        	sqlSentence = "Select * from posicion_pelota where id_partido="+
	        	               MainModel.getIdPartido()+" and ciclo="+ciclo;
		        stmt2 = connection.createStatement();
		        rs2 = stmt2.executeQuery(sqlSentence);
		        while (rs2.next()){
		        	posx = rs2.getDouble("x");
		        	posy = rs2.getDouble("y");
		        }
		        dim_pospelota = getPosPelota(posx,posy);
		        rs2.close();
		        stmt2.close();
	        	
		        nro_agente = rs.getString("nro_agente");
	        	agente_receptor = rs.getInt("nro_agente_receptor");
	        	
		        //Calculo la medida cantidad de pases
		        cant_pases = 1;
		        //Me fijo quien tiene la pelota en el proximo ciclo
		        /* Esto se comenta porque no tengo cargada la tabla jugador_pelota 
		        sqlSentence = "select * from jugador_pelota where id_partido = "+id_partido+
		                      " and ciclo > " + ciclo +" order by ciclo ";
		        stmt2 = connection.createStatement();
		        rs2 = stmt2.executeQuery(sqlSentence);
		        if (rs2.next()){
		        	if (rs2.getString("equipo").equalsIgnoreCase(MainModel.getLocatario())){
		        		//Si la tiene mi equipo
		        		cant_pases_ok = 1;
		        		cant_pases_nok = 0;
		        		if (agente_receptor == rs2.getInt("agente")){
		        			cant_pases_ok_coord = 1;
		        		}else{
		        			cant_pases_ok_coord = 0;
		        		}
		        	}else{
		        		cant_pases_nok = 1;
		        		cant_pases_ok = 0;
		        		cant_pases_ok_coord = 0;
		        	}
		        }
	        	rs2.close();
	        	stmt2.close();
		        */
		        if (elpasefueok(agente_receptor, ciclo)){
	        		cant_pases_nok = 0;
	        		cant_pases_ok = 1;
		        }else{
	        		cant_pases_nok = 1;
	        		cant_pases_ok = 0;
		        }
        		cant_pases_ok_coord = 0;
		        //Cargo la tabla
	        	sqlSentence = "Select * from hechos where id_acciones="+dim_acciones+
	        	              " and id_tiempo="+dim_tiempo+" and id_partidos="+id_partido+
	        	              " and id_pospelota="+dim_pospelota+" and id_agentes="+nro_agente;
		        stmt2 = connection.createStatement();
		        rs2 = stmt2.executeQuery(sqlSentence);
		        if (rs2.next()){
		        	//Existe el registro tengo que hacer un update
		        	sqlSentence = "update hechos set med_cantacciones = med_cantacciones +1, " +
		        	              " med_cantpases="+cant_pases+", med_cantpasesok="+cant_pases_ok+
		        	              ", med_cantpasesnok="+cant_pases_nok+
		        		          " where id_acciones="+dim_acciones+
	        	                  " and id_tiempo="+dim_tiempo+" and id_partido="+id_partido+
	        	                  " and id_pospelota="+dim_pospelota+" and id_agentes="+nro_agente;
		        	rs2.close();
		        	stmt2.close();
			        stmt2 = connection.createStatement();
			        stmt2.executeUpdate(sqlSentence);
		        	stmt2.close();
		        } else {
		        	sqlSentence = "insert into hechos(id_acciones, id_tiempo, id_partidos,"+
		        	              " id_pospelota, id_agentes, med_cantacciones, med_cantpases, med_cantpasesok,"+
		        	              " med_cantpasesokcoord, med_cantpasesnok) values ("+dim_acciones+","+dim_tiempo+","+
		        	              id_partido+","+dim_pospelota+","+nro_agente+",1,"+cant_pases+","+
		        	              cant_pases_ok+","+cant_pases_ok_coord+","+cant_pases_nok+")";
		        	rs2.close();
		        	stmt2.close();
			        stmt2 = connection.createStatement();
			        stmt2.executeUpdate(sqlSentence);
		        	stmt2.close();
		        }
	        }
	        connection.commit();
        }catch (SQLException e){
            try{
                connection.rollback();
            }catch (Exception e1){}
        }
	}

	private void cargarDimAcciones(String dim_acciones, String tabla){
		String sqlSentence = "";
	    Statement stmt, stmt2;
	    String id_partido = "", ciclo = "", nro_agente = "";
	    String dim_tiempo = "", dim_pospelota = "";
	    double posx = 0, posy = 0;
	    ResultSet rs, rs2;
	    Connection connection = MainModel.getDataBase().getConnection();
	    try{
	        sqlSentence = "Select * from "+tabla+" where id_partido = "+
	                       MainModel.getIdPartido();
	        MainModel.getLogger().logDebug("CargarCubos::procesar - Voy a ejecutar la sentencia: "+
	        		                        sqlSentence);
	        stmt = connection.createStatement();
	        rs = stmt.executeQuery(sqlSentence);
	        while (rs.next()){
	        	//dim_tiempo
	        	ciclo = rs.getString("ciclo");
	        	sqlSentence = "Select identificador from dim_tiempo where ciclo="+ciclo;
		        stmt2 = connection.createStatement();
		        rs2 = stmt2.executeQuery(sqlSentence);
		        while (rs2.next()){
		        	dim_tiempo = rs2.getString("identificador");
		        }
		        rs2.close();
		        stmt2.close();
	        	
		        //dim_partidos
	        	id_partido = rs.getString("id_partido");

	        	//dim_pospelota
	        	sqlSentence = "Select * from posicion_pelota where id_partido="+
	        	               MainModel.getIdPartido()+" and ciclo="+ciclo;
		        stmt2 = connection.createStatement();
		        rs2 = stmt2.executeQuery(sqlSentence);
		        while (rs2.next()){
		        	posx = rs2.getDouble("x");
		        	posy = rs2.getDouble("y");
		        }
		        dim_pospelota = getPosPelota(posx,posy);
		        rs2.close();
		        stmt2.close();
	        	
		        nro_agente = rs.getString("nro_agente");
	        	
	        	sqlSentence = "Select * from hechos where id_acciones="+dim_acciones+
	        	              " and id_tiempo= "+dim_tiempo+" and id_partidos="+id_partido+
	        	              " and id_pospelota="+dim_pospelota+" and id_agentes="+nro_agente;
		        MainModel.getLogger().logDebug("CargarCubos::procesar - Voy a ejecutar la sentencia: "+
                        sqlSentence);
		        stmt2 = connection.createStatement();
		        rs2 = stmt2.executeQuery( sqlSentence);
		        if (rs2.next()){
		        	//Existe el registro tengo que hacer un update
		        	sqlSentence = "update hechos set med_cantacciones = med_cantacciones +1 " +
		        		          " where id_acciones="+dim_acciones+
	        	                  " and id_tiempo="+dim_tiempo+" and id_partidos="+id_partido+
	        	                  " and id_pospelota="+dim_pospelota+" and id_agentes="+nro_agente;
		        	rs2.close();
		        	stmt2.close();
			        stmt2 = connection.createStatement();
			        stmt2.executeUpdate(sqlSentence);
		        	stmt2.close();
		        } else {
		        	sqlSentence = "insert into hechos(id_acciones, id_tiempo, id_partidos, id_pospelota, id_agentes,"+
		        	              " med_cantacciones) values ("+dim_acciones+","+dim_tiempo+","+id_partido+","+
		        	              dim_pospelota+","+nro_agente+",1)";
		        	rs2.close();
		        	stmt2.close();
			        stmt2 = connection.createStatement();
			        stmt2.executeUpdate(sqlSentence);
		        	stmt2.close();
		        }
	        }
	        connection.commit();
        }catch (SQLException e){
            try{
                connection.rollback();
            }catch (Exception e1){}
        }
	}
	
	private String getPosPelota(double posx, double posy){
		String dim_pospelota = "";
        if ( -52.5 <= posx && posx < -36){
        	//Zona defensa
        	if ( 16.5 <= posy && posy < 34){
        		//Zona 1
        		dim_pospelota = "1";
        	} else if ( -16.5 <= posy && posy < 16.5){
        		//Zona 2
        		dim_pospelota = "2";
        	} else {
        		//Zona 3
        		dim_pospelota = "3";
        	}
        } else if ( -36 <= posx && posx < 0){
        	//Zona Medio Defensa
        	if ( 16.5 <= posy && posy < 34){
        		//Zona 4
        		dim_pospelota = "4";
        	} else if ( -16.5 <= posy && posy < 16.5){
        		//Zona 5
        		dim_pospelota = "5";
        	} else {
        		//Zona 6
        		dim_pospelota = "6";
        	}
        } else if ( 0 <= posx && posx < 36){
        	//Zona Medio Ataque
        	if ( 16.5 <= posy && posy < 34){
        		//Zona 7
        		dim_pospelota = "7";
        	} else if ( -16.5 <= posy && posy < 16.5){
        		//Zona 8
        		dim_pospelota = "8";
        	} else {
        		//Zona 9
        		dim_pospelota = "9";
        	}
        } else if ( 36 <= posx && posx <= 52.5){
        	//Zona Medio Defensa
        	if ( 16.5 <= posy && posy < 34){
        		//Zona 10
        		dim_pospelota = "10";
        	} else if ( -16.5 <= posy && posy < 16.5){
        		//Zona 11
        		dim_pospelota = "11";
        	} else {
        		//Zona 12
        		dim_pospelota = "12";
        	}
        }
	    return dim_pospelota;
	}

	private void cargarIndicadores(){
		String sqlSentence = "";
	    Statement stmt, stmt2;
	    String indicador = "";
	    ResultSet rs;
	    Connection connection = MainModel.getDataBase().getConnection();
	    try{
	        sqlSentence = "Select * from indicadores where id_partido = "+
	                       MainModel.getIdPartido()+" and nombre_var in "+getVariablesIndACargar();
	        MainModel.getLogger().logDebug("CargarCubos::procesar - Voy a ejecutar la sentencia: "+
	        		                        sqlSentence);
	        stmt = connection.createStatement();
	        rs = stmt.executeQuery(sqlSentence);
	        while (rs.next()){
	        	indicador = rs.getString("identificador");
	        	System.out.println(indicador);
	        	sqlSentence = "insert into hechos_indicadores(id_partido,id_indicador,med_valor)"+
	        	              " values ("+MainModel.getIdPartido()+","+indicador+","+rs.getFloat("valor")+")";
		        stmt2 = connection.createStatement();
		        stmt2.executeUpdate(sqlSentence);
	        	stmt2.close();
	        }
	        connection.commit();
        }catch (SQLException e){
            try{
                connection.rollback();
            }catch (Exception e1){}
        }
	}
	private String getVariablesIndACargar() {
		String l = "";
		String linea = "";
		try {
			BufferedReader r = new BufferedReader(new FileReader("cfg/kpisForCube.cfg"));
			while ((linea = r.readLine()) != null) {
				if (!l.equals("")) l = l+",";
				l = l + "'"+linea+"'";
			}
		} catch (FileNotFoundException e) {
		} catch (IOException e) {
		}
		return "("+l+")";
	}

	private boolean elpasefueok( int nro_agente, String ciclo){
		boolean retorno = false;
		String sqlSentence = "";
		int cicloParcial = 0;
	    Statement stmt;
	    ResultSet rs;
	    Connection connection = MainModel.getDataBase().getConnection();
	    try{
	        sqlSentence = "Select * from acciones_clearball where id_partido = "+
	                       MainModel.getIdPartido()+" and ciclo > "+ciclo+" order by ciclo";
	        stmt = connection.createStatement();
	        rs = stmt.executeQuery(sqlSentence);
	        if (rs.next()){
	        	retorno = rs.getInt("nro_agente") == nro_agente;
	        	cicloParcial = rs.getInt("ciclo");
	        }
	        rs.close();
	        stmt.close();
	        
	        sqlSentence = "Select * from acciones_dribble where id_partido = "+
	        	MainModel.getIdPartido()+" and ciclo > "+ciclo+" and ciclo < "+cicloParcial+" order by ciclo";
	        stmt = connection.createStatement();
	        rs = stmt.executeQuery(sqlSentence);
	        if (rs.next()){
	        	//Si el que hizo el dribble es el agente destino, el pase fue ok
	        	retorno = rs.getInt("nro_agente") == nro_agente;
	        	cicloParcial = rs.getInt("ciclo");
	        }
	        rs.close();
	        stmt.close();
	    
	        sqlSentence = "Select * from acciones_intercept where id_partido = "+
        		MainModel.getIdPartido()+" and ciclo > "+ciclo+" and ciclo < "+cicloParcial+" order by ciclo";
	        stmt = connection.createStatement();
	        rs = stmt.executeQuery(sqlSentence);
	        if (rs.next()){
	        	//Si alguien hizo un intercept entonces el pase fue errado
	        	retorno = false;
	        	cicloParcial = rs.getInt("ciclo");
	        }
	        rs.close();
	        stmt.close();
        
	        sqlSentence = "Select * from acciones_passto where id_partido = "+
    			MainModel.getIdPartido()+" and ciclo > "+ciclo+" and ciclo < "+cicloParcial+" order by ciclo";
	        stmt = connection.createStatement();
        	rs = stmt.executeQuery(sqlSentence);
        	if (rs.next()){
	        	//Si el que hizo el pase es el agente destino, el pase fue ok
	        	retorno = rs.getInt("nro_agente") == nro_agente;
	        	cicloParcial = rs.getInt("ciclo");
        	}
        	rs.close();
        	stmt.close();
        	
	        sqlSentence = "Select * from acciones_score where id_partido = "+
	        	MainModel.getIdPartido()+" and ciclo > "+ciclo+" and ciclo < "+cicloParcial+" order by ciclo";
	        stmt = connection.createStatement();
	        rs = stmt.executeQuery(sqlSentence);
	        if (rs.next()){
	        	//Si el que hizo el tiro es el agente destino, el pase fue ok
	        	retorno = rs.getInt("nro_agente") == nro_agente;
	        	cicloParcial = rs.getInt("ciclo");
	        }
	        rs.close();
	        stmt.close();
        	
        }catch (SQLException e){
            try{
                connection.rollback();
            }catch (Exception e1){}
        }
		return retorno;
	}
}

