<?php
/* * ********************************************************************
*  ProxmoxVPS Product developed. (26.03.19)
* *
*
*  CREATED BY MODULESGARDEN       ->       http://modulesgarden.com
*  CONTACT                        ->       contact@modulesgarden.com
*
*
* This software is furnished under a license and may be used and copied
* only  in  accordance  with  the  terms  of such  license and with the
* inclusion of the above copyright notice.  This software  or any other
* copies thereof may not be provided or otherwise made available to any
* other person.  No title to and  ownership of the  software is  hereby
* transferred.
*
*
* ******************************************************************** */

use Illuminate\Database\Capsule\Manager as DB;
use ModulesGarden\ProxmoxAddon\App\Repositories\Vps\ProductConfigurationRepository;
use ModulesGarden\Servers\ProxmoxVps\App\Enum\ConfigurableOption;

$hookManager->register(
    function ($vars)
    {
        if ($vars['filename'] != 'upgrade' || $_REQUEST['step'] != 2)
        {
            return;
        }
        try
        {
            if (!function_exists('ModuleBuildParams'))
            {
                require_once ROOTDIR . DIRECTORY_SEPARATOR . 'includes' . DIRECTORY_SEPARATOR . "modulefunctions.php";
            }
            global $smartyvalues;
            $displayUpgradePage = true;
            /* @var $request \ModulesGarden\Servers\ProxmoxVps\Core\Http\Request */
            $request = \ModulesGarden\Servers\ProxmoxVps\Core\Helper\sl("request");
            /**
             * @var \ModulesGarden\Servers\ProxmoxVps\Core\Lang\Lang $lang
             */
            $lang      = \ModulesGarden\Servers\ProxmoxVps\Core\Helper\sl("lang");
            $serviceId = $request->get('id');
            $h         = 'tblhosting';
            $p         = 'tblproducts';
            $hosting   = \WHMCS\Service\Service::select("{$h}.*")
                ->leftJoin($p, "{$p}.id", '=', "{$h}.packageid")
                ->where("{$h}.id", $serviceId)
                ->where("{$h}.userid", $request->getSession('uid'))
                ->where("{$p}.servertype", 'proxmoxVPS')
                ->first();
            if (!$hosting)
            {
                return;
            }
            // Disk Downsize Protection chosen product as smaller disk size than the current server disk size
            if ($request->get('type') && $request->get('pid') && $request->get('type') == "package")
            {
                $newProductId = $request->get('pid');
                $newProduct   = new ProductConfigurationRepository($newProductId);
                $newDisk      = $newProduct->getDiskSize();
                \ModulesGarden\ProxmoxAddon\App\Services\Utility::unitFormat($newDisk, "gb", 'bytes');
                //Current
                $product = new ProductConfigurationRepository($hosting->productId);
                $disk    = $product->getDiskSize();
                \ModulesGarden\ProxmoxAddon\App\Services\Utility::unitFormat($disk, "gb", 'bytes');
                if ($newDisk < $disk)
                {
                    $newSize                    = \ModulesGarden\ProxmoxAddon\App\Libs\Format::convertBytes($newDisk);
                    $size                       = \ModulesGarden\ProxmoxAddon\App\Libs\Format::convertBytes($disk);
                    $smartyvalues['promoerror'] = $lang->abtr("You cannot select a product which disk size is lower than the one you currently have.");
                    $displayUpgradePage         = false;
                }
            }
            else
            {
                if ($request->get('configoption'))
                { //chosen configurable option value for disk size is smaller than the current server disksize
                    $configoptions = getCartConfigOptions($hosting->productId, $request->get('configoption'), $hosting->billingcycle);
                    $params        = \ModuleBuildParams($hosting->id);
                    $product       = new ProductConfigurationRepository($hosting->productId);
                    if ($params['configoptions'][ConfigurableOption::DISK_SIZE])
                    {
                        $disk = $params['configoptions'][ConfigurableOption::DISK_SIZE];
                        \ModulesGarden\ProxmoxAddon\App\Services\Utility::unitFormat($disk, $product->getDiskUnit(), 'bytes');
                    }
                    else
                    {
                        $disk = $product->getDiskSize();
                        \ModulesGarden\ProxmoxAddon\App\Services\Utility::unitFormat($disk, "gb", 'bytes');
                    }
                    //additional disks size
                    if (isset($params['configoptions'][ConfigurableOption::ADDITIONAL_DISKS_SIZE]))
                    {
                        $additionalDisksSpace = $params['configoptions'][ConfigurableOption::ADDITIONAL_DISKS_SIZE];
                        \ModulesGarden\ProxmoxAddon\App\Services\Utility::unitFormat($additionalDisksSpace, $product->getAdditionalDiskUnit(), 'bytes');
                    }
                    else
                    {
                        $additionalDisksSpace =  $product->getAdditionalDiskSize();
                        \ModulesGarden\ProxmoxAddon\App\Services\Utility::unitFormat($additionalDisksSpace, "gb", 'bytes');
                    }
                    foreach ($configoptions as $configoption)
                    {
                        if (isset($params['configoptions']['']) || $configoption['hidden'])
                        {
                            continue;
                        }
                        $moduleName = DB::table('tblproductconfigoptions')->where('id', $configoption['id'])->value('optionname');
                        if (preg_match('/\|/', $moduleName))
                        {
                            $ex         = explode("|", $moduleName);
                            $moduleName = $ex[0];
                        }
                        if (!$moduleName || !isset($params['configoptions'][$moduleName]))
                        {
                            continue;
                        }
                        if ($configoption['selectedqty'] != 0)
                        {
                            $params['configoptions'][$moduleName] = $configoption['selectedqty'];
                            continue;
                        }
                        foreach ($configoption['options'] as $option)
                        {
                            if ($configoption['selectedvalue'] == $option['id'])
                            {
                                if (preg_match('/\|/', $option['rawName']))
                                {
                                    $ex                = explode("|", $option['rawName']);
                                    $option['rawName'] = $ex[0];
                                }
                                $params['configoptions'][$moduleName] = $option['rawName'];
                                break;
                            }
                        }
                    }
                    if ($params['configoptions'][ConfigurableOption::DISK_SIZE])
                    {
                        $newDisk = $params['configoptions'][ConfigurableOption::DISK_SIZE];
                        \ModulesGarden\ProxmoxAddon\App\Services\Utility::unitFormat($newDisk, $product->getDiskUnit(), 'bytes');
                    }
                    else
                    {
                        $newDisk = $product->getDiskSize();
                        \ModulesGarden\ProxmoxAddon\App\Services\Utility::unitFormat($newDisk, "gb", 'bytes');
                    }
                    if ($newDisk < $disk)
                    {
                        $newSize                    = \ModulesGarden\ProxmoxAddon\App\Libs\Format::convertBytes($newDisk);
                        $size                       = \ModulesGarden\ProxmoxAddon\App\Libs\Format::convertBytes($disk);
                        $smartyvalues['promoerror'] = sprintf($lang->abtr("You are not able to set %s of Disk Size. Current Disk Size: %s. Disk downgrading is not supported."), $newSize, $size);
                        $displayUpgradePage         = false;
                    }
                    //Additonal Disk Downsize Protection
                    if (isset($params['configoptions'][ConfigurableOption::ADDITIONAL_DISKS_SIZE]))
                    {
                        $newAdditionalDisksSpace = $params['configoptions'][ConfigurableOption::ADDITIONAL_DISKS_SIZE];
                        \ModulesGarden\ProxmoxAddon\App\Services\Utility::unitFormat($newAdditionalDisksSpace, $product->getAdditionalDiskUnit(), 'bytes');
                    }
                    else
                    {
                        $newAdditionalDisksSpace =  $product->getAdditionalDiskSize();
                        \ModulesGarden\ProxmoxAddon\App\Services\Utility::unitFormat($newAdditionalDisksSpace, "gb", 'bytes');
                    }
                    if($newAdditionalDisksSpace < $additionalDisksSpace && $params['customfields']['node'] && $params['customfields']['vmid']){
                        $api = \MGProvision\Proxmox\v2\Factory::api($params);
                        $vm = \MGProvision\Proxmox\v2\Factory::vmVps($product, $params);
                        $vm->setApi($api);
                        $used = 0;
                        if($vm instanceof  \MGProvision\Proxmox\v2\models\Lxc){
                            $used = $vm->getMounPoints()->additionalSizeToBytes();
                        }elseif ($vm instanceof  \MGProvision\Proxmox\v2\models\Kvm){
                            foreach ($vm->getHardDisks() as $hd){
                                if($hd->isMaster()){
                                    continue;
                                }
                                $used += $hd->getBytes();
                            }
                        }
                        if($used > $newAdditionalDisksSpace){
                            $smartyvalues['promoerror'] = $lang->abtr("Disk downgrading is not possible until you remove additional disks.");
                            $displayUpgradePage = false;
                        }
                    }
                }
            }
            $isLoadBalancer = \ModulesGarden\ProxmoxAddon\App\Models\ProductConfiguration::ofProductId($hosting->productId)->ofSetting("loadBalancer")->ofValue('"on"')->count();
            //LoadBalancer is enabled?
            if ($isLoadBalancer && $displayUpgradePage)
            {
                $product = new ProductConfigurationRepository($hosting->productId);
                //LoadBalancer on upgrade
                $onUpgrade = $product->getLoadBalancerOnUpgrade();
                if ($onUpgrade == "none" || !$onUpgrade)
                {
                    return;
                }

                $configoptions = getCartConfigOptions($hosting->productId, $request->get('configoption'), $hosting->billingcycle);
                $params        = \ModuleBuildParams($hosting->id);
                foreach ($configoptions as $configoption)
                {
                    if (isset($params['configoptions']['']) || $configoption['hidden'])
                    {
                        continue;
                    }
                    $moduleName = DB::table('tblproductconfigoptions')->where('id', $configoption['id'])->value('optionname');
                    if (preg_match('/\|/', $moduleName))
                    {
                        $ex         = explode("|", $moduleName);
                        $moduleName = $ex[0];
                    }
                    if (!$moduleName || !isset($params['configoptions'][$moduleName]))
                    {
                        continue;
                    }
                    if ($configoption['selectedqty'] != 0)
                    {
                        $params['configoptions'][$moduleName] = $configoption['selectedqty'];
                        continue;
                    }
                    foreach ($configoption['options'] as $option)
                    {
                        if ($configoption['selectedvalue'] == $option['id'])
                        {
                            if (preg_match('/\|/', $option['rawName']))
                            {
                                $ex                = explode("|", $option['rawName']);
                                $option['rawName'] = $ex[0];
                            }
                            $params['configoptions'][$moduleName] = $option['rawName'];
                            break;
                        }
                    }
                }
                $loadBalancer = new \ModulesGarden\ProxmoxAddon\App\Services\LoadBalancerService($params['serverid']);
                $api          = \MGProvision\Proxmox\v2\Api::whmcsFactory($params);
                $api->debug(\ModulesGarden\ProxmoxAddon\App\Models\ModuleSettings::isDebug());
                $loadBalancer->setApi($api);
                if ($product->isQemu())
                {
                    $socket = $params['configoptions'][ConfigurableOption::SOCKETS] ? $params['configoptions'][ConfigurableOption::SOCKETS] : $product->getSockets();
                    $cores  = $params['configoptions'][ConfigurableOption::CORES_PER_SOCKET] ? $params['configoptions'][ConfigurableOption::CORES_PER_SOCKET] : $product->getCores();
                    $cpu    = $socket * $cores;
                }
                else
                {
                    if ($product->isLxc())
                    {
                        $cpu = $params['configoptions'][ConfigurableOption::CORES] ? $params['configoptions'][ConfigurableOption::CORES] : $product->getCores();
                    }
                }
                //disk
                if ($params['configoptions'][ConfigurableOption::DISK_SIZE])
                {
                    $newDisk = $params['configoptions'][ConfigurableOption::DISK_SIZE];
                    \ModulesGarden\ProxmoxAddon\App\Services\Utility::unitFormat($newDisk, $product->getDiskUnit(), 'bytes');
                }
                else
                {
                    $newDisk = $product->getDiskSize();
                    \ModulesGarden\ProxmoxAddon\App\Services\Utility::unitFormat($newDisk, "gb", 'bytes');
                }
                //ram
                if ($params['configoptions'][ConfigurableOption::MEMORY])
                {
                    $ram = $params['configoptions'][ConfigurableOption::MEMORY];
                    \ModulesGarden\ProxmoxAddon\App\Services\Utility::unitFormat($ram, $product->getMemoryUnit(), 'bytes');
                }
                else
                {
                    $ram = $product->getMemory();
                    \ModulesGarden\ProxmoxAddon\App\Services\Utility::unitFormat($ram, "mb", 'bytes');
                }
                $loadBalancer->setExcludeVmid($params['customfields']['vmid']);
                //Upgrade on current node
                if ($onUpgrade == "block")
                {
                    $loadBalancerNodes = $loadBalancer->findByNode($params['customfields']['node']);
                    $loadBalancerNodes = $loadBalancerNodes->findByRam($ram)
                        ->findByCpu($cpu)
                        ->findByDisk($disk);
                    if (!$loadBalancerNodes->isEmpty())
                    {
                        return;
                    }
                    $smartyvalues['promoerror'] = $lang->abtr("You cannot upgrade there no free resurces on our server");
                    $displayUpgradePage         = false;
                }
                else
                {
                    if ($onUpgrade == "migrate")
                    {
                        try
                        {
                            $loadBalancerNodes = $loadBalancer->findByNode($params['customfields']['node']);
                            $loadBalancerNodes = $loadBalancerNodes->findByRam($ram)
                                ->findByCpu($cpu)
                                ->findByDisk($disk);
                            if (!$loadBalancerNodes->isEmpty())
                            {
                                return;
                            }
                            $loadBalancerNodes = $loadBalancer->findByVmCreate();
                            $nodesForUser      = $loadBalancer->findNotUser($params['userid']);
                            if (!$nodesForUser->isEmpty())
                            {
                                $loadBalancerNodes = $nodesForUser;
                            }
                            $targetNode = $loadBalancerNodes->findByRam($ram)
                                ->findByCpu($cpu)
                                ->findByDisk($disk)
                                ->findByVms(1)
                                ->nodeLowLoad();

                            $smartyvalues['promoerror'] = $lang->abtr("Your machine will be migrated to another server");
                        }
                        catch (\Exception $ex)
                        {
                            $smartyvalues['promoerror'] = $lang->abtr("You cannot migrate there no free resurces on our server");
                            $displayUpgradePage         = false;
                        }
                    }
                }
            }
            if (!$displayUpgradePage)
            {
                return '<script type="text/javascript">
                        $(document).ready(function(){
                            //six
                            if($(".main-content .table").size()){
                                     $(".main-content .table").hide();
                                     $(".main-content .alert-info").hide();
                                     $(".main-content .row").hide();
                                     $(".main-content .form-group .btn").hide();
                                     var form  = $(".container .row .panel .panel-footer form").clone();
                                     $(".main-content .form-group.text-center").append(form );
                                     $(".main-content .form-group.text-center .btn-block ").removeClass("btn-block");
                            }
                            //Control
                             if($("#main-content .col-md-12").size()){
                                  $("#main-content .col-md-12").hide();
                             }
                           
                        });
                    </script>';
            }
        }
        catch (\Exception $ex)
        {
            logModuleCall(
                'ProxmoxVPS',
                __FUNCTION__,
                $vars,
                $ex->getMessage(),
                $ex->getTraceAsString()
            );
        }

    }
);
