<?php

namespace GoGetSSL;

class API
{
    private $url = 'https://my.gogetssl.com/api';
    private $key = null;
    private $lastStatus = null;
    private $lastResponse = null;

    public function __construct($key = null)
    {
        if ($key) {
            $this->key = $key;
        }
    }


    public function setUrl($url)
    {
        $this->url = $url;
    }


    public function auth($user, $pass)
    {

        $response = $this->call('/auth/', array(), array('user' => $user, 'pass' => $pass));

        if (!empty($response['key'])) {
            $this->key = $response['key'];
            return $response;
        }

        return false;
    }


    public function setKey($key)
    {
        if ($key) {
            $this->key = $key;
        }
    }


    public function decodeCSR($csr, $brand = 1, $wildcard = 0)
    {

        if (!$this->key) {
            throw new AuthException();
        } else {
            $getData = array('auth_key' => $this->key);
        }


        if ($csr) {
            $postData['csr'] = $csr;
            $postData['brand'] = $brand;
            $postData['wildcard'] = $wildcard;
        }

        return $this->call('/tools/csr/decode/', $getData, $postData);
    }


    public function getWebServers($type)
    {

        if (!$this->key) {
            throw new AuthException();
        } else {
            $getData = array('auth_key' => $this->key);
        }

        return $this->call('/tools/webservers/' . (int)$type, $getData);
    }


    public function getDomainEmails($domain)
    {

        if (!$this->key) {
            throw new AuthException();
        } else {
            $getData = array('auth_key' => $this->key);
        }


        if ($domain) {
            $postData['domain'] = $domain;
        }

        return $this->call('/tools/domain/emails/', $getData, $postData);
    }


    public function getDomainEmailsForGeotrust($domain)
    {

        if (!$this->key) {
            throw new AuthException();
        } else {
            $getData = array('auth_key' => $this->key);
        }


        if ($domain) {
            $postData['domain'] = $domain;
        }

        return $this->call('/tools/domain/emails/geotrust/', $getData, $postData);
    }

    public function getDomainAlternative($csr)
    {

        if (!$this->key) {
            throw new AuthException();
        } else {
            $getData = array('auth_key' => $this->key);
        }


        if ($csr) {
            $postData['csr'] = $csr;
        }

        return $this->call('/tools/domain/alternative/', $getData, $postData);
    }


    public function getAllProductPrices()
    {

        if (!$this->key) {
            throw new AuthException();
        } else {
            $getData = array('auth_key' => $this->key);
        }

        return $this->call('/products/all_prices/', $getData);
    }


    public function getAllProducts()
    {

        if (!$this->key) {
            throw new AuthException();
        } else {
            $getData = array('auth_key' => $this->key);
        }

        return $this->call('/products/', $getData);
    }


    public function getProductDetails($productId)
    {

        if (!$this->key) {
            throw new AuthException();
        } else {
            $getData = array('auth_key' => $this->key);
        }

        return $this->call('/products/details/' . $productId, $getData);
    }


    public function getProductPrice($productId)
    {

        if (!$this->key) {
            throw new AuthException();
        } else {
            $getData = array('auth_key' => $this->key);
        }

        return $this->call('/products/price/' . $productId, $getData);
    }


    public function getUserAgreement($productId)
    {

        if (!$this->key) {
            throw new AuthException();
        } else {
            $getData = array('auth_key' => $this->key);
        }

        return $this->call('/products/agreement/' . $productId, $getData);
    }


    public function getAccountBalance()
    {

        if (!$this->key) {
            throw new AuthException();
        } else {
            $getData = array('auth_key' => $this->key);
        }

        return $this->call('/account/balance/', $getData);
    }


    public function getAccountDetails()
    {

        if (!$this->key) {
            throw new AuthException();
        } else {
            $getData = array('auth_key' => $this->key);
        }

        return $this->call('/account/', $getData);
    }


    public function getTotalOrders()
    {

        if (!$this->key) {
            throw new AuthException();
        } else {
            $getData = array('auth_key' => $this->key);
        }

        return $this->call('/account/total_orders/', $getData);
    }


    public function getAllInvoices()
    {

        if (!$this->key) {
            throw new AuthException();
        } else {
            $getData = array('auth_key' => $this->key);
        }

        return $this->call('/account/invoices/', $getData);
    }


    public function getUnpaidInvoices()
    {

        if (!$this->key) {
            throw new AuthException();
        } else {
            $getData = array('auth_key' => $this->key);
        }

        return $this->call('/account/invoices/unpaid/', $getData);
    }


    public function getTotalTransactions()
    {

        if (!$this->key) {
            throw new AuthException();
        } else {
            $getData = array('auth_key' => $this->key);
        }

        return $this->call('/account/total_transactions/', $getData);
    }


    public function addSSLOrder($data)
    {

        if (!$this->key) {
            throw new AuthException();
        } else {
            $getData = array('auth_key' => $this->key);
        }

        return $this->call('/orders/add_ssl_order/', $getData, $data);
    }


    public function addSSLRenewOrder($data)
    {

        if (!$this->key) {
            throw new AuthException();
        } else {
            $getData = array('auth_key' => $this->key);
        }

        return $this->call('/orders/add_ssl_renew_order/', $getData, $data);
    }


    public function reIssueOrder($orderId, $data)
    {

        if (!$this->key) {
            throw new AuthException();
        } else {
            $getData = array('auth_key' => $this->key);
        }

        return $this->call('/orders/ssl/reissue/' . (int)$orderId, $getData, $data);
    }


    public function activateSSLOrder($orderId)
    {

        if (!$this->key) {
            throw new AuthException();
        } else {
            $getData = array('auth_key' => $this->key);
        }

        return $this->call('/orders/ssl/activate/' . (int)$orderId, $getData);
    }


    public function getOrderStatus($orderId)
    {

        if (!$this->key) {
            throw new AuthException();
        } else {
            $getData = array('auth_key' => $this->key);
        }

        return $this->call('/orders/status/' . (int)$orderId, $getData);
    }


    public function getOrderInvoice($orderId)
    {

        if (!$this->key) {
            throw new AuthException();
        } else {
            $getData = array('auth_key' => $this->key);
        }

        return $this->call('/orders/invoice/' . (int)$orderId, $getData);
    }


    public function getUnpaidOrders()
    {

        if (!$this->key) {
            throw new AuthException();
        } else {
            $getData = array('auth_key' => $this->key);
        }

        return $this->call('/orders/list/unpaid/', $getData);
    }


    public function resendEmail($orderId)
    {

        if (!$this->key) {
            throw new AuthException();
        } else {
            $getData = array('auth_key' => $this->key);
        }

        return $this->call('/orders/ssl/resend_validation_email/' . (int)$orderId, $getData);
    }


    public function changeValidationEmail($orderId, $postData)
    {

        if (!$this->key) {
            throw new AuthException();
        } else {
            $getData = array('auth_key' => $this->key);
        }

        return $this->call('/orders/ssl/change_validation_email/' . (int)$orderId, $getData, $postData);
    }


    public function call($uri, $getData = array(), $postData = array(), $forcePost = false, $isFile = false)
    {
        $url = $this->url . $uri;

        if (!empty($getData)) {
            foreach ($getData as $key => $value) {
                $url .= (strpos($url, '?') !== false ? '&' : '?') . urlencode($key) . '=' . rawurlencode($value);
            }
        }

        $post = ((!empty($postData) || $forcePost) ? true : false);

        $ch = curl_init($url);

        if ($post) {
            curl_setopt($ch, CURLOPT_POST, true);
        }

        if (!empty($postData)) {
            $queryData = (($isFile) ? $postData : http_build_query($postData));
            curl_setopt($ch, CURLOPT_POSTFIELDS, $queryData);
        }

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        $result = curl_exec($ch);
        $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        $this->lastStatus = $status;
        $this->lastResponse = json_decode(strstr($result, '{'), true);

        $apiError = trim(strstr($result, '{', true));

        if (!empty($apiError)) {
            logActivity('GoGetSSL API error(s) which has been removed from the JSON string what could case an invalid output; URI: "' . $uri . '", error: "' . $apiError . '", getData: "' . print_r($getData, true) . '", postData: "' . print_r($postData, true) . '"');
        }

        if (isset($this->lastResponse['description']) && stripos($this->lastResponse['description'], 'gogetssl') !== false) {
            logActivity('GoGetSSL API returned description that contains "gogetssl", stripped due whitelabeling; URI: "' . $uri . '", description: "' . $this->lastResponse['description'] . '", getData: "' . print_r($getData, true) . '", postData: "' . print_r($postData, true) . '"');
            $this->lastResponse['description'] = 'Unknown error';
        }

        return $this->lastResponse;
    }


    public function getLastStatus()
    {
        return $this->lastStatus;
    }


    public function getLastResponse()
    {
        return $this->lastResponse;
    }
}
