/*
 * InvestorController.java
 *
 * Created on November 1, 2007, 10:17 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package uc2;

import java.util.*;
import java.sql.*;
import java.io.*;
//import boundary.*;
//import entity.*;

public class InvestorController {
    List<PortfolioData> investorsList = new ArrayList<PortfolioData>();
    // define resultSet here as global varialbe
    // resultSet = 
    class PortfolioData {
        long InvestorID;
        double alpha = 0.0;
        double beta = 0.0;
        double residue = 0.0;
        double exp_return = 0.0;
        double total_gain = 0.0;
        double variance = 0.0;
        double sharpe_ratio = 0.0;
        double value = 0.0;
    }

    int maxNumOfTrials;
    int failCounts = 0;

    /** Creates a new instance of InvestorController */
    public InvestorController() {
        maxNumOfTrials = 3;
        failCounts = 0;
        investorsList.clear();
    }

    int getMaxNumOfTrial() {
        return (maxNumOfTrials);
    }
    
    int getNumOfTrial() {
        return (failCounts);
    }

    void incrementFailCounts() {
        failCounts++; 
    }

    boolean getInvestors(){
        // Need to connect to DatabaseCommunicator()
        ResultSet rs = null;
        DatabaseCommunicator.connect();
        try {
            String query = "SELECT investor_id FROM investor;";
            rs = DatabaseCommunicator.query(query);
            while(rs.next()) {
                PortfolioData portfolioData = new PortfolioData();
                portfolioData.InvestorID = rs.getInt("investor_id");
                investorsList.add(portfolioData);
            } 
            DatabaseCommunicator.close();
            System.out.println("Size of investorsList = " + investorsList.size());
            return(investorsList.size()>0);
        }
        catch (Exception e) {
                System.err.println("Exception: " + e.toString());
        }
        return( false );
    }

    public void updateInvestorsPortfolioParameters() 
    {
        // Need to update the portfolio alpha, beta and risk in investor's profile
        DatabaseCommunicator.connect();
        try 
        {
            for(int i = 0; i < investorsList.size(); i++)
            {
                PortfolioData portfolioData = (PortfolioData) investorsList.get(i);
                DatabaseCommunicator.query("UPDATE investor SET alpha = " + portfolioData.alpha + " WHERE investor_id = " + portfolioData.InvestorID + ";");
                DatabaseCommunicator.query("UPDATE investor SET beta = " + portfolioData.beta + " WHERE investor_id = " + portfolioData.InvestorID + ";");
                DatabaseCommunicator.query("UPDATE investor SET residue = " + portfolioData.residue + " WHERE investor_id = " + portfolioData.InvestorID + ";");
                DatabaseCommunicator.query("UPDATE investor SET exp_return = " + portfolioData.exp_return + " WHERE investor_id = " + portfolioData.InvestorID + ";");
                DatabaseCommunicator.query("UPDATE investor SET variance = " + portfolioData.variance + " WHERE investor_id = " + portfolioData.InvestorID + ";");
                DatabaseCommunicator.query("UPDATE investor SET portfolio_value = " + portfolioData.value + " WHERE investor_id = " + portfolioData.InvestorID + ";");
                DatabaseCommunicator.query("UPDATE investor SET sharpe_ratio = " + portfolioData.sharpe_ratio + " WHERE investor_id = " + portfolioData.InvestorID + ";");
                DatabaseCommunicator.query("UPDATE investor SET total_gain = " + portfolioData.total_gain + " WHERE investor_id = " + portfolioData.InvestorID + ";");
            }
            DatabaseCommunicator.close();
        }
        catch (Exception e) 
        {
            System.err.println("Exception: " + e.toString());
        }
    }

    public void printPortfolioParameters(PortfolioData portfolioData)
    {
        System.out.println();
        System.out.println("investorID      =   " + portfolioData.InvestorID);
        System.out.println("Portfolio Value =   " + portfolioData.value);        
        System.out.println("Total Gain      =   " + portfolioData.total_gain);
        System.out.println("Expected Return =   " + portfolioData.exp_return);
        System.out.println("Variance        =   " + portfolioData.variance);        
        System.out.println("Sharpe Ratio    =   " + portfolioData.sharpe_ratio);
        System.out.println("alpha value     =   " + portfolioData.alpha);
        System.out.println("beta value      =   " + portfolioData.beta);
        System.out.println("Residue         =   " + portfolioData.residue);
    }
    
    public void portfolioRiskAnalysis() {
        int investID = 0;

        while(getNumOfTrial() < getMaxNumOfTrial() & getInvestors() == false) {
            incrementFailCounts();
            System.out.println("Connection fails " + getNumOfTrial() + " times");
        }
        
        if(getNumOfTrial() >= getMaxNumOfTrial()) {
            System.out.println("Connection fails more than " + getMaxNumOfTrial() + " times, please contact Server Admin for resolution.");
            System.exit(-1);  // No investor at all.
        }

        // loop through resultSet and to perform risk analysis of investor's portfolio
        ListIterator<PortfolioData> investor = investorsList.listIterator();
        while(investor.hasNext()) {
            PortfolioData portfolioData = (PortfolioData) investorsList.get(investID);
            PortfolioEvaluator portfolioEval = new PortfolioEvaluator();
            if(portfolioEval.evaluatePortfolioParameters(portfolioData.InvestorID) == true) {
                portfolioEval.updatePortfolioParameters(portfolioData.InvestorID);
                portfolioData.alpha = portfolioEval.alpha_p;
                portfolioData.beta = portfolioEval.beta_p;
                portfolioData.residue = portfolioEval.risk_p;
                portfolioData.exp_return = portfolioEval.exp_return_p;
                portfolioData.variance = portfolioEval.variance_p;
                portfolioData.sharpe_ratio = portfolioEval.sharpe_ratio;
                portfolioData.value = portfolioEval.value_p;
                portfolioData.total_gain = portfolioEval.ttl_gain_p;
                printPortfolioParameters(portfolioData);
            }
            investID++;
            investor.next();
        }
        updateInvestorsPortfolioParameters();
        ValueAtRisk.calculateValueAtRisk();
    }    
}