<?php
/**
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * @copyright (c) ProudCommerce | 2020
 * @link          www.proudcommerce.com
 * @package       psCacheWarmer
 * @version       3.1.1
 **/

namespace ProudCommerce\CacheWarmer\Core;

use OxidEsales\Eshop\Core\Registry;
use OxidEsales\Eshop\Core\ViewConfig;
use ProudCommerce\CacheWarmer\Application\Model\Constants;

/**
 * Class CacheWarmer
 *
 * @package ProudCommerce\CacheWarmer\Core
 */
class CacheWarmer
{
    private string $sCliSiteMapFile = '';

    /**
     *
     */
    public function run($sFileSitemap)
    {
        $this->sCliSiteMapFile = trim($sFileSitemap);

        $aUrls = $this->_getSitemapContent();
        if ((!empty($this->getModulConfigurationAsString('psCacheWarmerSitemapUrl',Constants::OXID_MODULE_ID))
                || !empty($sFileSitemap))
            && !empty($aUrls)) {
            foreach ($aUrls as $sUrl) {
                $oCurl = $this->_runCurlConnect($sUrl);
                $this->_checkCurlResults($oCurl, $sUrl);
                curl_close($oCurl);
            }
        }
    }

    /**
     * @param $sUrl
     *
     * @return false|resource
     */
    protected function _runCurlConnect($sUrl)
    {
        $oCurl = curl_init();
        curl_setopt($oCurl, CURLOPT_URL, $sUrl);
        curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($oCurl, CURLOPT_CONNECTTIMEOUT, 25);
        curl_setopt($oCurl, CURLOPT_HEADER, true);
        curl_setopt($oCurl, CURLOPT_USERAGENT, 'CacheWarmer');
        $sUsername = $this->getModulConfigurationAsString('psCacheWarmerUser',Constants::OXID_MODULE_ID);
        $sPassword = $this->getModulConfigurationAsString('psCacheWarmerPass',Constants::OXID_MODULE_ID);
        curl_setopt($oCurl, CURLOPT_USERPWD, $sUsername . ":" . $sPassword);
        curl_exec($oCurl);

        return $oCurl;
    }

    /**
     * @param $oCurl
     * @param $sUrl
     */
    protected function _checkCurlResults($oCurl, $sUrl)
    {
        $httpStatus = curl_getinfo($oCurl, CURLINFO_HTTP_CODE);
        if (curl_error($oCurl)) {
            $sStatusMsg = 'ERROR';
            $sMessage = curl_error($oCurl);
        } else {
            $sMessage = $sUrl;
            if (in_array(trim($httpStatus), $this->getModulConfigurationAsCollection('psCacheWarmerHttpCodes',Constants::OXID_MODULE_ID))) {
                $sStatusMsg = 'OK';
            } else {
                $sStatusMsg = 'ERROR';
            }
        }
        $httpStatus = trim($httpStatus);
        $aLog = [$sStatusMsg, $httpStatus, $sMessage];
        print_r($aLog);

        if (!empty($aLog) && (($this->getModulConfigurationAsBool('psCacheWarmerWriteCsvOnlyError', Constants::OXID_MODULE_ID) && $httpStatus != '200')
                || $this->getModulConfigurationAsBool('psCacheWarmerWriteCsv', Constants::OXID_MODULE_ID))) {
            $logger = Logging::getLogger('psCacheWarmer', Registry::getConfig()->getLogsDir() . 'pscachewarmer_' . date("dmY_His") . '.log');
            $logger->info(implode(' | ', $aLog) . "\r");
        }
    }

    /**
     * @param string $sSitemapUrl
     *
     * @return array
     */
    protected function _getSitemapContent($sSitemapUrl = "")
    {
        $aUrls = [];
        if (empty($sSitemapUrl) && $this->sCliSiteMapFile == '')
        {
            $sSitemapUrl = $this->_getSitemapUrl($sSitemapUrl);
        }
        elseif (empty($sSitemapUrl) && $this->sCliSiteMapFile != '')
        {
            $sSitemapUrl = $this->_getSitemapUrl($this->sCliSiteMapFile);
        }
        $sUsername = $this->getModulConfigurationAsString('psCacheWarmerUser',Constants::OXID_MODULE_ID);
        $sPassword = $this->getModulConfigurationAsString('psCacheWarmerPass',Constants::OXID_MODULE_ID);
        $sSitemapUrl = str_replace("://", "://" . $sUsername . ":" . $sPassword . "@", $sSitemapUrl);

        $sSitemapXmlData = @file_get_contents($sSitemapUrl);
        if ($oSitemap = @simplexml_load_string($sSitemapXmlData)) {
            if (count($oSitemap->sitemap) > 0) {
                foreach ($oSitemap->sitemap as $oSubSitemap) {
                    $sNextSitemapUrl = (string) $oSubSitemap->loc;
                    $aUrls = array_merge($aUrls, $this->_getSitemapContent($sNextSitemapUrl));
                }
            }

            if (count($oSitemap->url) > 0) {
                foreach ($oSitemap->url as $oSitemapUrl) {
                    $aUrls[] = (string) $oSitemapUrl->loc;
                }
            }
        }

        return $aUrls;
    }

    /**
     * @return string
     */
    protected function _getSitemapUrl($sSitemapFile)
    {
        $sSitemapUrl = Registry::getConfig()->getShopURL();

        if($sSitemapFile != '')
        {
            $sSitemapUrl .= $sSitemapFile;
        }
        else{
            $sSitemapUrl .= $this->getModulConfigurationAsString('psCacheWarmerSitemapUrl',Constants::OXID_MODULE_ID);
        }

        return $sSitemapUrl;
    }

    /**
     * @param string $sParam
     * @param string $sModulId
     * @return bool
     */
    public function getModulConfigurationExists(string $sParam, string $sModulId)
    {
        return Registry::get(ViewConfig::class)->d3GetModulConfigurationExists($sParam, $sModulId);
    }

    /**
     * @param string $sParam
     * @param string $sModulId
     * @return string
     */
    public function getModulConfigurationAsString(string $sParam, string $sModulId)
    {
        return Registry::get(ViewConfig::class)->d3GetModulConfigurationAsString($sParam, $sModulId);
    }

    /***
     * @param string $sParam
     * @param string $sModulId
     * @return int
     */
    public function getModulConfigurationAsInteger(string $sParam, string $sModulId)
    {
        return Registry::get(ViewConfig::class)->d3GetModulConfigurationAsInteger($sParam, $sModulId);
    }

    /**
     * @param string $sParam
     * @param string $sModulId
     * @return float
     */
    public function getModulConfigurationAsFloat(string $sParam, string $sModulId)
    {
        return Registry::get(ViewConfig::class)->d3GetModulConfigurationAsFloat($sParam, $sModulId);
    }

    /**
     * @param string $sParam
     * @param string $sModulId
     * @return bool
     */
    public function getModulConfigurationAsBool(string $sParam, string $sModulId)
    {
        #return $this->d3getModulConfigurationAsBool($sParam, $sModulId);
        return Registry::get(ViewConfig::class)->d3GetModulConfigurationAsBool($sParam, $sModulId);
    }

    /**
     * @param string $sParam
     * @param string $sModulId
     * @return array
     */
    public function getModulConfigurationAsCollection(string $sParam, string $sModulId)
    {
        return Registry::get(ViewConfig::class)->d3GetModulConfigurationAsCollection($sParam, $sModulId);
    }
}