<?php
/**
 * Exchange Rates Service Layer
 * 
 * @see https://openexchangerates.org/documentation
 * 
 * @author Neil Corke <neil@corkeweb.com>
 *
 */
class Forex_ExchangeRateService
{
    /**
     * The Open Exchange Rates link
     */
    private $oer = 'https://openexchangerates.org';
    
    
    /**
     * The api key
     */
    private $apikey = 'fcbdcbf66fa2410c98aa117ba9d3174a';
    
    
    /**
     * FxRates Zend Table
     *
     * @var FxRates Table
     */
    protected $rates;
     
    
    /**
     * The database adapater
     *
     */
    protected $db;
     
    
    /**
     * Master Database
     */
    protected $masterDB = 'falk_master';
     
    
    /**
     *
     * Instantiate the FxRates table model
     */
    function __construct()
    {
    	// Get the default db adapter:
    	$this->db = Zend_Db_Table::getDefaultAdapter();
    	Zend_Db_Table_Abstract::setDefaultAdapter($this->db);
    	 
    	$this->rates = new Default_Model_FxRatesTable();
    	 
    	// The master database name:
    	$this->masterDB = Zend_Registry::get('masterDb');
    }
      
    
    /**
     * Fetch the current days exchange rates from openexchangerates.org
     * 
     * @return multitype JSON string of all rates
     */
    public function fetchCurrentRates()
    {     
        $url = $this->oer . '/api/latest.json?app_id=' . $this->apikey;
        $result = file_get_contents($url);
        
        return $this->calculateRates($result);    
    }
  	
    
    /**
     * Fetch the past days exchange rates from openexchangerates.org
     *
     * @return multitype JSON string of all rates
     */
    public function fetchHistoricRates($date)
    {    
        $url = $this->oer . '/api/historical/' . $date . '.json?app_id=' . $this->apikey;
        $result = file_get_contents($url);
        
        return $this->calculateRates($result);    
    }
    
    
    /**
     * Update daily exchange rates record (create new record if none exists)
     * 
     * @param array   $rateArray - the exchange rates 
     * @param date    $date - the record date
     * 
     * @throws Zend_Controller_Exception
     */
    public function saveRates($rateArray, $date)
    {      
        // Check for existing record:
        $select = $this->rates->select();
    	$select->from(array('fx' => $this->masterDB . '.ForeignExchangeRates'),
    			      array('COUNT(fx.GBPEUR)'))
    			      
    	       ->where('exchangeDate = ?', $date);
    
    	$existingRecord = $this->db->fetchOne($select);
    	
    	// If new rates returned:
    	if($rateArray['EURGBP'] > 0) {
   		      
            // If record already exists:
            if ($existingRecord) {
                
                $data = $rateArray;        
                $data['updates'] = new Zend_Db_Expr('updates + 1');
                $data['updated'] = new Zend_Db_Expr('NOW()');
                
                $where = $this->rates->getAdapter()->quoteInto('exchangeDate = ?', $date);
                
                $this->rates->update($data, $where);         
                
            } else { // Create new record:
                       
                $data = $rateArray;
                $data['exchangeDate'] = $date;
                $data['updates'] = 1;
                $data['updated'] = new Zend_Db_Expr('NOW()');
                
                $where = $this->rates->getAdapter()->quoteInto('exchangeDate = ?', $date);
                
                $this->rates->insert($data);
            }	

    	} else {
    	    
    	    throw new Zend_Controller_Exception('No data array received');
    	}
    }
      
    
    /**
     * Calculate the required exchange rates
     * 
     * @param multitype $response - JSON string of all rates
     * @param int       $decPlaces - number of decimal places to return
     * 
     * @throws Zend_Controller_Exception
     * 
     * @return array
     * 
     */
    private function calculateRates($response, $decPlaces = 5) 
    {   
        if ($response) {
            
            $fxArray = Zend_Json::decode($response, true);
            
            $USDRate = $fxArray['rates']['USD'];         
            $EURRate = $fxArray['rates']['EUR'];
            $GBPRate = $fxArray['rates']['GBP'];
            
            $rates = array();        
            $rates['GBPEUR'] = round($EURRate / $GBPRate, $decPlaces);
            $rates['GBPUSD'] = round($USDRate / $GBPRate, $decPlaces);
            $rates['EURGBP'] = round($GBPRate / $EURRate, $decPlaces);
            $rates['EURUSD'] = round($USDRate / $EURRate, $decPlaces);
            $rates['USDGBP'] = round($GBPRate, $decPlaces);
            $rates['USDEUR'] = round($EURRate, $decPlaces);

            return $rates;
            
        } else {
        
            throw new Zend_Controller_Exception('FX rate array missing!');
        }
    }
}