<?php

class Atmail_Provider_SIP_YTL extends Atmail_Provider_SIP_Abstract
{


	private $fieldMap = array(
		"Account" => "Account", 
		"src"=>"src", 
		"dst"=>"dst", 
		"startUnixGMT"=>"startUnixGMT", 
		"answerUnixGMT"=>"answerUnixGMT", 
		"endUnixGMT"=>"endUnixGMT", 
		"durationSecs"=>"durationSecs", 
		"disposition"=>"disposition"
	);
	public function __construct( Array $configArray )
	{
		
		//Zend_Registry::get('log')->debug( "\n" . print_r($configArray, true) . "\n" . __METHOD__ . ' #' . __LINE__ . ": \$configArray \n");
		if( parent::__construct($configArray) === false )
			return false;

		$this->dbAdapter = Zend_Registry::get('dbAdapter');
		if( !array_key_exists("PhoneNumber", $configArray) )
				throw new Exception("PhoneNumber field missing");
		if( !array_key_exists("Account", $this->_config) )
				throw new Exception("Account field missing");
		$this->PhoneNumber = $configArray['PhoneNumber'];
		$this->Account = $this->_config['Account'];
		//Zend_Registry::get('log')->debug( __METHOD__ . ' #' . __LINE__ . ": Finished constructor");
	}
	
	public function create( Array $args = array() ) //not allowed to be publically called, only from abstracted class
	{
		
		//Zend_Registry::get('log')->debug( "\n" . print_r($args, true) . "\n" . __METHOD__ . ' #' . __LINE__ . ": \$args \n");
		
		$requiredFields = array("src","dst","startUnixGMT","disposition");
		//create call record in the local user cdr
		foreach( $requiredFields as $v )
		{
			
			if( !array_key_exists($v, $args) )
				throw new Exception("Field missing from query: " . $v);
			
		}
		$newRecord = array('Account'=>$args['Account']);
		foreach( $args as $k => $v )
		{
			
			if( array_key_exists($k, $args) )
			{
				
				$newRecord[$k] = $v;
				
			}
			
		}
		$numberOfAffectedRows = $this->dbAdapter->insert("cdr", $newRecord);
			
		if( $numberOfAffectedRows == 1 )
			return array('response' => array('message' => "Call record added"), 'status' =>'success');
		else
			return array('response' => array('message' => "Failed adding call record"), 'status' => 'failed' );
		
	}
	
	public function getSummary( Array $args = array() )
	{
		
		//Zend_Registry::get('log')->debug( "\n" . print_r($args, true) . "\n" . __METHOD__ . ' #' . __LINE__ . ": \$args \n");
		$searchTerms = array();
			
		foreach( array('src', 'dst') as $v )
		{
			if ( array_key_exists($v, $args) )
				$searchTerms[] = "$v LIKE " . $this->dbAdapter->quote('%' . $args[$v] . '%');
		}
		$searchTerms = implode(" OR ",$searchTerms);
		$periodFromUnixGMT = 0;
		//TODO: timeframe and paging
		
		$q = "
		SELECT 
		cdr1.cdrId AS id, 
		cdr1.*, 
		cdrLatest.isLatest, 
		AbookSrc.id AS srcAbookId, 
		AbookDst.id AS dstAbookId, 
		CONCAT( AbookSrc.UserFirstName, ' ', AbookSrc.UserLastName ) AS srcName, 
		CONCAT( AbookDst.UserFirstName, ' ', AbookDst.UserLastName ) AS dstName, 
		IF(AbookSrc.UserHomePhone = cdr1.src,'UserHomePhone','Phone') AS srcDevice, 
		IF(AbookDst.UserHomePhone = cdr1.dst,'UserHomePhone','Phone') AS dstDevice, 
		(" . $this->dbAdapter->quote($this->PhoneNumber) . " = cdr1.src ) AS outbound
		FROM 
		(
			SELECT * 
			FROM cdr
			WHERE 
				Account = " . $this->dbAdapter->quote($this->Account) . " 
				AND startUnixGMT >= " . $this->dbAdapter->quote($periodFromUnixGMT);
		if( strlen($searchTerms) > 0 )
			$q .= " AND ($searchTerms)";
		$q .= "
			ORDER BY cdrId DESC
		) AS cdr1
		LEFT JOIN Abook AS AbookSrc ON cdr1.src = AbookSrc.UserHomePhone
		LEFT JOIN Abook AS AbookDst ON cdr1.dst = AbookDst.UserHomePhone
		LEFT JOIN 
		(
			SELECT cdrId, 1 AS isLatest 
			FROM 
			(
				SELECT * 
				FROM cdr
				WHERE 
					Account = " . $this->dbAdapter->quote($this->Account) . " 
					AND startUnixGMT >= " . $this->dbAdapter->quote($periodFromUnixGMT) . " 
					ORDER BY cdrId DESC
			) as cdr2
			GROUP BY src, dst 
		) AS cdrLatest ON cdr1.cdrId = cdrLatest.cdrId
		";
		
		//Zend_Registry::get('log')->debug("\n" . print_r($q, true) . "\n" . __METHOD__ . ' #' . __LINE__ . ": $q \n");
		
		$rows = $this->dbAdapter->fetchAll($q);
		//Zend_Registry::get('log')->debug( "\n" . print_r($rows, true) . "\n" . __METHOD__ . ' #' . __LINE__ . ": \$rows \n");
		
		foreach( $rows as &$row )
		{
			
			$row['startLocale'] = date('r',$row['startUnixGMT']);
			$row['answerLocale'] = date('r',$row['answerUnixGMT']);
			$row['endLocale'] = date('r',$row['endUnixGMT']);
			foreach( $this->fieldMap as $public => $internal )
			{
				if( $public != $internal )
				{
					$row[$public] = $row[$internal];
					unset($row[$internal]);
				}
			}
			unset($row['Account']);
			
		}
		
		//now switch off isLAtest ro calls matched in the opposite dir
		foreach( $rows as $k => $v )
		{
			
			if( $k == 0 )
				continue;
			
			//before adding each row, check if any earlier rows match call in the reverse dir to the same person
			for( $i = 0 ; $i < $k ; $i++ )
			{
				
				if( $rows[$i]['src'] == $v['dst'] && $rows[$i]['dst'] == $v['src'] )
					$rows[$k]['isLatest'] = null;
				
			}
			
		}
		return array("status" => "success", "totalNumberOfItems" => count($rows), "page" => 1, "itemsPerPage" => count($rows), "serviceData" => $rows);
	
	}
	
	public function getList( Array $args = array() )
	{
        
		//Zend_Registry::get('log')->debug( "\n" . print_r($args, true) . "\n" . __METHOD__ . ' #' . __LINE__ . ": \$args \n");
		$searchTerms = array();
			
		foreach( array('src', 'dst') as $v )
		{
			if ( array_key_exists($v, $args) )
				$searchTerms[] = "$v LIKE " . $this->dbAdapter->quote('%' . $args[$v] . '%');
		}
		$searchTerms = implode(" OR ",$searchTerms);
		//TODO: timeframe and paging
		$q = "SELECT 
		cdr.*, 
		CONCAT(AbookSrc.UserFirstName, ' ', AbookSrc.UserLastName) AS srcName, 
		CONCAT(AbookDst.UserFirstName, ' ', AbookDst.UserLastName) AS dstName, 
		(" . $this->dbAdapter->quote($this->PhoneNumber) . " = src ) AS outbound
		FROM cdr 
		LEFT JOIN Abook AS AbookSrc ON src = AbookSrc.UserHomePhone
		LEFT JOIN Abook AS AbookDst ON dst = AbookDst.UserHomePhone
		WHERE cdr.Account=" . $this->dbAdapter->quote($this->Account) . " AND (src LIKE " . $this->dbAdapter->quote('%' . $this->PhoneNumber . '%') . " OR dst LIKE " . $this->dbAdapter->quote('%' . $this->PhoneNumber . '%') . ")";
		if( strlen($searchTerms) > 0 )
			$q .= " AND ($searchTerms)";
		$q .= " ORDER BY cdrId DESC";
		//Zend_Registry::get('log')->debug("\n" . print_r($q, true) . "\n" . __METHOD__ . ' #' . __LINE__ . ": $q \n");
		
		$rows = $this->dbAdapter->fetchAll($q);
		//Zend_Registry::get('log')->debug( "\n" . print_r($rows, true) . "\n" . __METHOD__ . ' #' . __LINE__ . ": \$rows \n");
		
		foreach( $rows as &$row )
		{
			
			$row['startLocale'] = date('r',$row['startUnixGMT']);
			$row['answerLocale'] = date('r',$row['answerUnixGMT']);
			$row['endLocale'] = date('r',$row['endUnixGMT']);
			foreach( $this->fieldMap as $public => $internal )
			{
				if( $public != $internal )
				{
					$row[$public] = $row[$internal];
					unset($row[$internal]);
				}
			}
			unset($row['Account']);
			
		}
		return array("status" => "success", "totalNumberOfItems" => count($rows), "page" => 1, "itemsPerPage" => count($rows), "serviceData" => $rows);
		
	}

	public function delete( Array $args )
	{
		
		if( array_key_exists('id', $args) )
			$itemsAffected = $this->dbAdapter->query("DELETE FROM cdr WHERE Account=? AND (src=? OR dst=?) AND cdrId=?", array( $this->Account, $this->PhoneNumber, $this->PhoneNumber, $args['cdrId'] ))->rowCount();
		else if( array_key_exists('src', $args)  )
			$itemsAffected = $this->dbAdapter->query("DELETE FROM cdr WHERE Account=? AND dst=? AND src=?", array( $this->Account, $this->PhoneNumber, $args['src']))->rowCount();
		else if( array_key_exists('dst', $args)  )
			$itemsAffected = $this->dbAdapter->query("DELETE FROM cdr WHERE Account=? AND src=? AND dst=?", array( $this->Account, $this->PhoneNumber, $args['dst']))->rowCount();
		else if( array_key_exists('deleteAll', $args) && $args['deleteAll'] == true  )
			$itemsAffected = $this->dbAdapter->query("DELETE FROM cdr WHERE Account=? AND (src=? OR dst=?)", array( $this->Account, $this->PhoneNumber, $this->PhoneNumber))->rowCount();
		else
			throw new Exception("Need deleteAll flag in order to force celeetion of all records");
		return array('response' => array('message' => "Call records deleted"), 'status' => 'success', "numberOfRecordsDeleted" => $itemsAffected);	
		
	}
	
	public function getInfo( Array $args = array() )
	{
		return null;
	}
	
	private function mapToInternal( $publicField )
	{
		
		if( array_key_exists($publicField, $this->fieldMap) )
			return $this->fieldMap[$publicField];
		else
			return $publicField;
		
	}

	private function mapToPublic( $internalField )
	{
		
		$result = array_search($internalField, $this->fieldMap);
		if( $result )
			return $result;
		else
			return $internalField;
		
	}

	
}
