package app.PREPROCESSING;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Petr Flégl on 23.12.2016.
 */
public class Preprocesor {


    List<PrepConf> confList = new ArrayList<>();
    int maxRows = 0;
    List<List<Double>>  data = new ArrayList<>();

    public Preprocesor(List<PrepConf> confList) {
        this.confList = confList;


        final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
        final String DB_URL = "jdbc:mysql://localhost/predictorDB";

        final String USER = "predictor";
        final String PASS = "predictor";

        Connection conn = null;
        Statement stmt = null;
        try {
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            conn = DriverManager.getConnection(DB_URL, USER, PASS);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        if (conn!=null)
        try{
            String sqls = "";
            for (PrepConf c: confList ) {

                stmt = conn.createStatement();
                String sql = null;
                if(c.getDatumMax()>0)
                    sql = "SELECT "+c.getColumnName()+" FROM "+c.getTableName()+" WHERE " +c.getDatum() + " >= " +c.getDatumMin() + " AND " +c.getDatum() + " < "+c.getDatumMax();
                else
                    sql = "SELECT "+c.getColumnName()+" FROM "+c.getTableName()+" ORDER BY " +c.getDatum() + " DESC LIMIT 1";
                sqls+=sql+"\r\n";
                ResultSet rs = stmt.executeQuery(sql);
                List<Double> dataCol = new ArrayList<>();
                while(rs.next()) {

                    double val = rs.getDouble(1);
                    val = (((c.getScaleOutMax() - c.getScaleOutMin()) * (val - c.getScaleInMin()))/(c.getScaleInMax() - c.getScaleInMin())) + c.getScaleOutMin();
                    dataCol.add(val);

                }
                maxRows=Math.max(maxRows,dataCol.size());
                if(dataCol.size()<maxRows)
                    for (int i = dataCol.size(); i < maxRows;i++)
                        dataCol.add(Double.MAX_VALUE);
                data.add(dataCol);

                rs.close();
            }
            System.out.println(sqls);
        }catch(SQLException se){
            se.printStackTrace();
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            try{
                if(stmt!=null)
                    conn.close();
            }catch(SQLException se){
            }
            try{
                if(conn!=null)
                    conn.close();
            }catch(SQLException se){
                se.printStackTrace();
            }
        }


        }






    public double[][] getData() {
        double dataOut[][] = new double[confList.size()][maxRows];
        if (data.size()>0 && data.get(0).size()>0)
            for (int y = 0; y < maxRows; y++) {
                for (int x=0; x<confList.size(); x++) {
                    if (data.get(x).get(y) != Double.MAX_VALUE) {
                        dataOut[x][y] = data.get(x).get(y).doubleValue();
                    }
                }
            }
        return dataOut;
    }

    public List<List<Double>> getDataList(){
        return data;
    }

    public double[][] getAverageData(){
        double dataOut[][] = new double[confList.size()][1];
        int rowCnt[] = new int[confList.size()];
        for (int y=0; y<maxRows; y++)
        {
            for (int x=0;x<confList.size();x++){
                if (data.get(x).get(y)!=Double.MAX_VALUE) {
                    dataOut[x][0] += data.get(x).get(y);
                    rowCnt[x]++;
                }
            }
        }

        for (int x=0;x<confList.size();x++){
            dataOut[x][0]=dataOut[x][0]/rowCnt[x];
        }

        return dataOut;
    }

    public double[][] getMovingAverageData(int subsetSize){
        double dataOut[][] = new double[confList.size()][maxRows-subsetSize-1];
        int rowCnt[] = new int[confList.size()];
        for (int n=0; n<maxRows-subsetSize-1; n++)
        {
            for (int y=n; y<n+subsetSize; y++)
            {
                for (int x=0;x<confList.size();x++){
                    if (data.get(x).get(y)!=Double.MAX_VALUE) {
                        dataOut[x][n] += data.get(x).get(y);
                        rowCnt[x]++;
                    }
                }
            }
            for (int x=0;x<confList.size();x++){
                dataOut[x][n]=dataOut[x][n]/rowCnt[x];
            }
        }


        return dataOut;
    }
}