<?php

namespace MGModule\DNSManager2\mgLibs\custom\dns\submodules\InterWorx;

class InterworxAPI {
    
    private $apis = array('siteworx', 'nodeworx');
    private $api;
    private $hostname;
    private $port;
    private $ssl;
    private $email;
    private $password;
    private $apikey;
    private $authmethod;
    private $domain;
    private $query = '';
    private $log_enabled = true;

    private $soap_point = 'soap?wsdl';
    
    private static $instance = false;
    
    /**
     * 
     * @param string $hostname
     * @param int $port
     * @param int $ssl
     * @param array $params
     */
    public function __construct($params = array()) {
        try {
            $this->isSoap();
        }
        catch (\Exception $exc) {
            throw new \MGModule\DNSManager2\mgLibs\custom\dns\exceptions\DNSSubmoduleException($exc->getMessage());
        }
        
        $this->hostname     = $params['serverip'] ?: $params['serverhostname'];
        $this->port         = $params['serverport'] ?: ($params['serversecure'] ? '2443' : '2080');
        $this->email        = $params['serverusername'] ?: '';
        $this->password     = $params['serverpassword'] ?: '';
        $this->apikey       = $params['serveraccesshash'] ?: '';
        $this->authmethod   = $params['serveraccesshash'] ? '2': '1';
        $this->domain       = $params['domain'] ?: '';
        $this->ssl          = $params['serversecure'] ?: '0';
        
    }
    
    /**
     * 
     */
    public function __clone() {
        
    }
    
    /**
     * 
     * @param string $name
     * @param mixed $arguments
     * @return mixed
     * @throws InterworxException
     */
    public function __call($name, $arguments) {
        if(!$this->api || !$this->query) {
            throw new \MGModule\DNSManager2\mgLibs\custom\dns\exceptions\DNSSubmoduleException("Invalid request.");
            
        }
        
        $conf = array(
                'trace'         => 1,
                'cache_wsdl'    => WSDL_CACHE_NONE,
                'features'      => SOAP_SINGLE_ELEMENT_ARRAYS,
                'exceptions' => 1,
                "stream_context" => stream_context_create(
                array(
                    'ssl' => array(
                    'verify_peer'       => false,
                    'verify_peer_name'  => false,
                    )
                )
            )
            );
        
        
        $url = ($this->ssl ? 'https' : 'http') . '://' . $this->hostname . ':' . $this->port . '/' .$this->soap_point;

        $client = new \SoapClient( $url , $conf);
        
        //Depending on authmethod and API type, various params are used to authenticate a user
        if($this->authmethod == 1) { //user and pass
            $key = array('email' => $this->email, 'password' => $this->password);
            if($this->api == 'siteworx') {
                $key['domain'] = $this->domain;
                
            }
        } else { //api key
            if($this->api == 'nodeworx') {
                $key = $this->apikey;
            } else {
                $key = array('domain' => $this->domain, 'apikey' => $this->apikey);
            }
        }

        $api_controller = '/' . $this->api . $this->query;
        $action = $name;
        $input = $arguments[0];

        $result = $client->route($key, $api_controller, $action, $input);
        
        if($this->log_enabled) {
            logModuleCall('Interworx', $api_controller.'/'.$action, $arguments, $result);
        }
        
        $this->api = $this->query = ''; //clear request string
        
        if($result['status'] != 0) 
        {
            $result_parts       = explode('Usage:', $result['payload']);
            $another_parts      = explode('Please see details below.', $result_parts[0]);
            $error = !empty($another_parts[1]) ? $another_parts[1] : $result['payload'];
            $result['payload']  = "Error - ". $error;
        }
        
        return $result;
    }
    
    /**
     * 
     * @param string $name
     * @throws InterworxException
     */
    public function __get($name) {
        if(in_array($name, $this->apis) && !$this->api) {
            $this->api = $name;
        } elseif($this->api) {
            $this->query .= '/' . $name;
        } else {
            throw new \MGModule\DNSManager2\mgLibs\custom\dns\exceptions\DNSSubmoduleException('This API is not allowed.');
        }
        return $this;
    }
    
    /**
     * 
     * @param array $params
     * @return object
     */
    public static function getInstance($params) {
        //if (self::$instance === false) {
            self::$instance = new self($params);
        //}

        return self::$instance;
    }
    
    /**
     * 
     * @throws InterworxException
     */
    public function isSoap() {
        if(!extension_loaded('soap')) {
            throw new \MGModule\DNSManager2\mgLibs\custom\dns\exceptions\DNSSubmoduleException("Soap extension cannot be loaded. Please make sure you have installed it on your server.");
        }
    }
    
    /**
     * 
     * @param int $port
     */
    public function setPort($port) {
        $this->port = $port;
    }
    
    /**
     * 
     * @param Interworx_AUTH $authmethod
     * @throws \InterworxException
     */
    public function setAuthmethod($authmethod) {
        if($authmethod != 2 && $authmethod != 1) {
            throw new \MGModule\DNSManager2\mgLibs\custom\dns\exceptions\DNSSubmoduleException('Unable to set authorization method. Choose between AUTH_APIKEY and AUTH_USERPASS.');
        }
        $this->authmethod = $authmethod;
    }
    
    /**
     * 
     * @param string $username
     */
    public function setUsername($username) {
        $this->email = $username;
    }
    
    /**
     * 
     * @param string $password
     */
    public function setPassword($password) {
        $this->password = $password;
    }
    
    /**
     * 
     * @param string $apikey
     */
    public function setApikey($apikey) {
        $this->apikey = $apikey;
    }
    
    /**
     * 
     * @param type $domain
     */
    public function setDomain($domain) {
        $this->domain = $domain;
    }
    
    public function disableLogging() {
        $this->log_enabled = false;
    }
    
    public function enableLogging() {
        $this->log_enabled = true;
    }
}