<?php
/**
 * CentovaCast management
 */
class Box_Mod_Servicecentovacast_Api_Admin extends Api_Abstract
{
    private $service = null;
    
    protected function init()
    {
        Box_Db::getRb();
        $mod = new Box_Mod('servicecentovacast');
        $this->service = $mod->getService();
    }
    
    /**
     * Return centovacast servers
     * 
     * @return boolean 
     */
    public function servers()
    {
        return $this->service->getServers();
    }
    
    /**
     * Get server pairs
     * 
     * @return array
     */
    public function server_pairs()
    {
        $servers = $this->service->getServers();
        $result = array();
        foreach($servers as $server) {
            $result[$server['id']] = $server['hostname'];
        }
        return $result;
    }
    
    /**
     * Add new centovacast server
     * 
     * @param type $data
     * @return int - server id 
     */
    public function server_add($data)
    {
        $bean = R::dispense('extension_meta');
        $bean->extension = 'mod_servicecentovacast';
        $bean->meta_key = 'server';
        $bean->meta_value = json_encode($data);
        $bean->created_at = date('c');
        $bean->updated_at = date('c');
        R::store($bean);
        
        $this->_log('Added new CentovaCast server %s', $bean->id);
        return $bean->id;
    }
    
    /**
     * Get server
     * 
     * @param int $id - server id
     * @return type
     * @throws Exception 
     */
    public function server_get($data)
    {
        if(!isset($data['id'])) {
            throw new Exception('Server id not passed');
        }
        return $this->service->getServer($data['id']);
    }
    
    /**
     * Update server
     * 
     * @param int $id - server id
     * @return bool
     * @throws Exception 
     */
    public function server_update($data)
    {
        $server = $this->server_get($data);
        $bean = R::findOne('extension_meta', 'id = :id', array('id'=>$server['id']));
        $bean->meta_value = json_encode($data);
        $bean->updated_at = date('c');
        R::store($bean);
        
        $this->_log('Updated CentovaCast server %s', $server['id']);
        return true;
    }
    
    /**
     * Remove server
     * 
     * @param int $id - server id
     * @return type
     * @throws Exception 
     */
    public function server_delete($data)
    {
        $server = $this->server_get($data);
        
        $sql="SELECT id FROM service_centovacast WHERE server_id = :sid LIMIT 1";
        $exists = R::getCell($sql, array('sid'=>$server['id']));
        if($exists) {
            throw new Exception('Server is used for active order. It can not be removed.');
        }
        
        $sql="DELETE FROM extension_meta WHERE id = :id";
        R::exec($sql, array('id'=>$server['id']));
        $this->_log('Removed CentovaCast server %s', $server['id']);
        return true;
    }
    
    /**
     * Test connection to server
     * 
     * @param int $id - server id
     * @return boolean
     * @throws Exception 
     */
    public function server_connection($data)
    {
        $server = $this->server_get($data);
        return $this->service->apiConnection($server);
    }
    
    /**
     * Update existing order service
     * 
     * @return boolean 
     */
    public function update($data)
    {
        list($order, $s) = $this->_getService($data);
        
        if(isset($data['username'])) {
            $s->username = $data['username'];
        }
        
        if(isset($data['pass'])) {
            $s->pass = $this->service->encryptPass($data['pass']);
        }
        
        $s->updated_at = date('c');
        R::store($s);
        
        $this->_log('Updated CentovaCast service %s details', $s->id);
        return true;
    }
    
    /**
     * Retrieves the configuration for a CentovaCast client account. 
     * If server-side streaming source support is enabled, 
     * the configuration for the streaming source is returned as well.
     * 
     * @param int $order_id - order id
     * @optional bool $try - do not throw an exception, return error message as a result
     * 
     * @return array
     */
    public function getaccount($data)
    {
        try {
            list($order, $model) = $this->_getService($data);
            $result = $this->service->getaccount($model);
        } catch(Exception $e) {
            error_log($e->getMessage());
            $result = array();
            if(!isset($data['try']) || !$data['try']) {
                throw $e;
            }
        }
        
        return $result;
    }
    
    /**
     * Returns the state (up or down) of one or more CentovaCast streaming 
     * server accounts. This can be used to monitor streams to see if any 
     * have crashed. (Note that CentovaCast's cron job automatically monitors 
     * and restarts crashed streaming servers as well.)

     * @param int $order_id - order id
     * @optional bool $try - do not throw an exception, return error message as a result
     * 
     * @return boolean 
     */
    public function info($data)
    {
        list($order, $model) = $this->_getService($data);
        
        try {
            $result = $this->service->info($model);
        } catch(Exception $e) {
            $result = $e->getMessage();
            if(!isset($data['try']) || !$data['try']) {
                throw $e;
            }
        }
        
        return $result;
    }
    
    /**
     * Updates the settings for an existing client streaming server 
     * account in CentovaCast.
     * 
     * @param int $order_id - order id
     * @return bool 
     */
    public function reconfigure($data)
    {
        list($order, $model) = $this->_getService($data);
        return $this->service->reconfigure($model, $data);
    }
    
    private function _getService($data)
    {
        if(!isset($data['order_id'])) {
            throw new Box_Exception('Order id is required');
        }
        
        $order = R::findOne('client_order',
                "id=:id 
                 AND service_type = 'centovacast'
                ", 
                array('id'=>$data['order_id']));
        
        if(!$order) {
            throw new Box_Exception('Centova Cast order not found');
        }
        
        $s = R::findOne('service_centovacast',
                'id=:id',
                array('id'=>$order->service_id));
        if(!$s) {
            throw new Box_Exception('Order :id is not activated', array(':id'=>$order->id));
        }
        return array($order, $s);
    }
}