package dataQualityWebSite;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.LinkedList;
import java.util.ListIterator;

public class FactorList extends LinkedList<FactorElement>
{

	private static final long serialVersionUID = 1L;
	private Statement selectFactorStatement;
	private ResultSet factorResultSet;
	private boolean factorFound;
	private Connection connection;
	private FactorElement factorElement;

	public FactorList(Connection connection)
	{
		this.connection = connection;
		
		try
		{
			selectFactorStatement = connection.createStatement();
		}
		catch(SQLException sqle)
		{
			System.out.println(sqle);
		}

		try
		{
			factorResultSet = selectFactorStatement.executeQuery
			(
				"select " +
					"id, " +
					"title, " +
					"description, " +
					"trend_or_zero_sum, " +
					"months_on_graph, " +
					"green_limit, " +
					"amber_limit, " +
				    "source_measured " +
				"from " +
					"factor " +
				"order by " +
				    "id"
			);

		}
		catch(SQLException sqle)
		{
			System.out.println(sqle);
		}

		factorFound = true;
		
		while(factorFound)
		{
			try
			{
				factorFound = factorResultSet.next();
			} 
			catch (SQLException e)
			{
				e.printStackTrace();
			}
			
			if (factorFound)
			{
				try
				{
 					factorElement = new FactorElement();
 					factorElement.setFactorId(factorResultSet.getInt("id"));
 					factorElement.setFactorTitle(factorResultSet.getString("title"));
 					factorElement.setDescription(factorResultSet.getString("description"));
 					factorElement.setFactorType(factorResultSet.getString("trend_or_zero_sum"));
 					factorElement.setMonthsOnGraph(factorResultSet.getInt("months_on_graph"));
 					factorElement.setGreenLimit(factorResultSet.getDouble("green_limit"));
 					factorElement.setAmberLimit(factorResultSet.getDouble("amber_limit"));
 					factorElement.setSourceMeasured(factorResultSet.getString("source_measured"));
 					factorElement.setFactorStatus("grey");
 					this.add(factorElement);
				} 
				catch (SQLException e)
				{
					e.printStackTrace();
				}
			}
		}
		try 
		{
			selectFactorStatement.close();
		} catch (SQLException e) 
		{
			e.printStackTrace();
		}
	}
	
	public void generate(Configuration configuration, LogFile logFile)
	{
		int dqFactorId = 0;
		double lastValue;
		String factorType;
		SeriesList seriesList;
		ListIterator<FactorElement> iterator;
		FactorElement factorElement;
		
		for (iterator = this.listIterator(); iterator.hasNext(); )
		{
			factorElement = (FactorElement) iterator.next();
			dqFactorId = factorElement.getFactorId();
			logFile.logMessage("Processing Factor " + dqFactorId);
			seriesList = new SeriesList(connection, factorElement);
			seriesList.calculate();
			factorType = new String(factorElement.getFactorType());
			if (factorType.equals("Trend"))
				factorElement.setFactorStatus(seriesList.getStatus());
			else       // Factor Type is Zero-sum 
			{
				if (seriesList.size() > 0)
				{
					lastValue = Math.abs(seriesList.getLastValue());
					if (lastValue > factorElement.getAmberLimit())
						factorElement.setFactorStatus("red");
					else if (lastValue > factorElement.getGreenLimit())
						factorElement.setFactorStatus("amber");
					else
						factorElement.setFactorStatus("green");
				}
			}

			new Detail(seriesList, factorElement, configuration);
			
			new SVGChart(seriesList, factorElement, configuration);			
		}
	}
	
	public void updateStatus(Configuration configuration, LogFile logFile)
	{
		int dqFactorId = 0;
		String factorStatus;
		ListIterator<FactorElement> iterator;
		FactorElement factorElement;
		String updateStatement;
		PreparedStatement updateFactor = null;
		
		
		updateStatement = new String
	    (
    		"update factor " +
	        "set " +
		        "red_amber_green_or_grey = ? , " +
	            "updated_at = now() " +
		    "where " +
	            "id = ? ;"
	    );
		
	    try 
	    {
			updateFactor = connection.prepareStatement(updateStatement);
		} 
	    catch (SQLException e) 
	    {
	    	logFile.logMessage("Factor " + dqFactorId + ": Cannot create update statement to record latest red/amber/green status" + e.getMessage());
		}


		for (iterator = this.listIterator(); iterator.hasNext(); )
		{
			factorElement = (FactorElement) iterator.next();
			dqFactorId = factorElement.getFactorId();
			factorStatus = new String(factorElement.getFactorStatus());
		    try 
		    {
				updateFactor.setString (1, factorStatus);
				updateFactor.setInt    (2, dqFactorId);
				updateFactor.executeUpdate();
			} 
		    catch (SQLException e) 
		    {
		    	logFile.logMessage("Factor " + dqFactorId + ": Cannot update latest red/amber/green status.  " + e.getMessage());
			}			
		}
	}
}
