<?php

use Illuminate\Database\Capsule\Manager as Capsule;

/**
 * Handles every request to GoGetSSL and will return an array with results.
 *
 * @param $command string command to execute
 * @param $params array A list of defined params
 * @param $tryFallback boolean Try fallback, used internally to prevents loops.
 * @return array|null
 */
function gogetssl_call($command, $params, $tryFallback = true)
{
    global $whmcs;

    $configuration = gogetssl_get_configuration();

    $apiKey = $whmcs->get_config('gogetssl_api_token');
    $apiKeyExpiry = $whmcs->get_config('gogetssl_api_token_expiry');

    if (!empty($apiKeyExpiry) && $apiKeyExpiry <= time()) {
        $apiKey = '';
    }

    if (!empty($apiKey)) {
        $api = new \GoGetSSL\API($apiKey);
    } else {
        $api = new \GoGetSSL\API();
    }

    if ($configuration['gogetssl_test']) {
        $api->setUrl('https://sandbox.gogetssl.com/api');
    } else {
        $api->setUrl('https://my.gogetssl.com/api');
    }

    if (empty($apiKey)) {
        $authResult = $api->auth(trim($configuration['gogetssl_username']), trim($configuration['gogetssl_password']));

        if (!isset($authResult['key'])) {
            return ['error' => true, 'description' => 'API password not valid'];
        }

        $whmcs->set_config('gogetssl_api_token', $authResult['key']);
        $whmcs->set_config('gogetssl_api_token_expiry', strtotime('+10 months'));
    }

    $callResult = null;

    switch ($command) {
        case 'getAllProducts':
            $callResult = $api->getAllProducts();
            break;

        case 'resendEmail':
            $callResult = $api->resendEmail($params['order_id']);
            break;

        case 'decodeCSR':
            $callResult = $api->decodeCSR($params['csr'], $params['brand'], $params['wildcard']);
            break;

        case 'getDomainEmailsForGeotrust':
            $callResult = $api->getDomainEmailsForGeotrust($params['domain']);
            break;

        case 'getDomainEmails':
            $callResult = $api->getDomainEmails($params['domain']);
            break;

        case 'addSSLOrder':
            $callResult = $api->addSSLOrder($params);
            break;

        case 'addSSLRenewOrder':
            $callResult = $api->addSSLRenewOrder($params);
            break;

        case 'getOrderStatus':
            $callResult = $api->getOrderStatus($params['order_id']);
            break;

        case 'getProductDetails':
            $callResult = $api->getProductDetails($params['product_id']);
            break;

        case 'reIssueOrder':
            $callResult = $api->reIssueOrder($params['order_id'], $params);
            break;

        case 'changeValidationEmail':
            $callResult = $api->changeValidationEmail($params['order_id'], $params);
            break;

        case 'getDomainAlternative':
            $callResult = $api->getDomainAlternative($params['csr']);
            break;
    }

    // Error with auth key, let's refresh it.
    if ($api->getLastStatus() == 403 && $tryFallback) {
        $whmcs->set_config('gogetssl_api_token', '');
        $whmcs->set_config('gogetssl_api_token_expiry', strtotime('-1 days'));

        $callResult = gogetssl_call($command, $params, false);
    }

    return $callResult;
}

/**
 * getSSLWebServerTypes() function will return an array of available webservers dependding on the supplier.
 *
 * @param "comodo"|null $supplier Either null or "comodo"
 * @return array all values
 */
function gogetssl_getSSLWebServerTypes($supplier)
{
    if ($supplier == 'comodo') {
        return [
            2 => 'Other',
            35 => 'IIS 7.x and later'
        ];
    }

    return [
        21 => 'Other',
        13 => 'IIS 7.x and later'
    ];
}

/**
 * Get a list of all available products from GoGetSSL.
 *
 * @return array list of products
 */
function gogetssl_getAllProducts()
{
    $productRequest = curlCall('https://my.gogetssl.com/api/certificates.json');

    $certList = json_decode($productRequest, true);

    if (is_array($certList)) {
        return $certList;
    }

    return array();
}

/**
 * Get the global configuration from the DB
 *
 * @return array
 */
function gogetssl_get_configuration()
{
    $settings = Capsule::table('tblconfiguration')
        ->where('setting', 'like', 'gogetssl_%')
        ->get();

    $return = [];

    foreach ($settings as $setting) {
        $return[$setting->setting] = ($setting->setting == 'gogetssl_tech') ? json_decode($setting->value) : $setting->value;
    }

    return $return;
}

/**
 * Return the translations for the current user
 *
 * Detects the language, if there isn't a file for this language in lang or lang/overrides, fallback to English.
 *
 * @param string $language Preferred language
 * @return array
 */
function gogetssl_translations($language = '')
{
    global $whmcs;

    if (empty($language)) {
        $language = ((isset($_SESSION['language'])) ? $_SESSION['language'] : $whmcs->get_config('Language'));
    }

    if (empty($language)) {
        $language = 'english';
    }

    if (!file_exists(__DIR__ . '/../lang/' . $language . '.php') && !file_exists(__DIR__ . '/lang/overrides/' . $language . '.php')) {
        $language = 'english';
    }

    if (file_exists(__DIR__ . '/../lang/' . $language . '.php')) {
        /* @var array $_SERVERLANG */
        require __DIR__ . '/../lang/' . $language . '.php';
    }

    if (file_exists(__DIR__ . '/../lang/overrides/' . $language . '.php')) {
        /* @var array $_SERVERLANG */
        require __DIR__ . '/../lang/overrides/' . $language . '.php';
    }

    return $_SERVERLANG;
}

/**
 * Get all possible validation options and it's values
 *
 * @param $domain
 * @param $csr
 * @param bool $comodo
 * @return mixed
 */
function gogetssl_get_validation($domain, $csr, $comodo = false, $mainDomain = null)
{
    $approver = [];

    // Get approver e-mails depending on brand
    $methodName = 'getDomainEmailsForGeotrust';
    $resultName = 'GeotrustApprovalEmails';

    if ($comodo) {
        $methodName = 'getDomainEmails';
        $resultName = 'ComodoApprovalEmails';
    }

    $domainEmailsResult = gogetssl_call($methodName, [
        'domain' => $domain
    ]);

    if (isset($domainEmailsResult['error'])) {
        return $domainEmailsResult['description'];
    }

    if (isset($domainEmailsResult[$resultName])) {
        foreach ($domainEmailsResult[$resultName] as $k => $v) {
            if (!empty($v)) {
                $approver['email'][] = $v;
            }
        }
    }

    // Get alternatives
    $domainAlternativeResult = gogetssl_call('getDomainAlternative', [
        'csr' => $csr
    ]);
    if (isset($domainAlternativeResult['error'])) {
        return $domainEmailsResult['description'];
    }
    $alternativeValues = $domainAlternativeResult['validation'];

    if ($mainDomain) {
        $approver['dns'] = str_replace($mainDomain, $domain, $alternativeValues['dns']['dns']['record']);
    } else {
        $approver['dns'] = $alternativeValues['dns']['dns']['record'];
    }

    $approver['http'] = [
        'link' => 'http://' . $domain . '/' . $alternativeValues['http']['http']['filename'],
        'filename' => $alternativeValues['http']['http']['filename'],
        'content' => $alternativeValues['http']['http']['content']
    ];

    $approver['https'] = [
        'link' => 'https://' . $domain . '/' . $alternativeValues['https']['https']['filename'],
        'filename' => $alternativeValues['https']['https']['filename'],
        'content' => $alternativeValues['https']['https']['content']
    ];

    return $approver;
}
