<?php

/* * ********************************************************************
 * ProxmoxAddon product developed. (Sep 19, 2018)
 * *
 *
 *  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.
 *
 *
 * ******************************************************************** */

namespace ModulesGarden\ProxmoxAddon\App\Cron;

use MGProvision\Proxmox\v2 as proxmox;
use ModulesGarden\ProxmoxAddon as main;
use ModulesGarden\ProxmoxAddon\App\Jobs\Vps\CloneQemuJob;
use ModulesGarden\ProxmoxAddon\App\Jobs\Vps\CreateLxcJob;
use ModulesGarden\ProxmoxAddon\App\Jobs\Vps\CreateQemuJob;
use ModulesGarden\ProxmoxAddon\App\Jobs\Vps\LoadBalancer\UpgradeVmJob;
use ModulesGarden\ProxmoxAddon\App\Jobs\Vps\MigrateVmJob;
use ModulesGarden\ProxmoxAddon\App\Jobs\Vps\Reinstall\CreateVmJob;
use ModulesGarden\ProxmoxAddon\App\Jobs\Vps\RestoreVm;
use ModulesGarden\ProxmoxAddon\App\Models\Job;
use ModulesGarden\ProxmoxAddon\App\Models\VmModel;
use ModulesGarden\ProxmoxAddon\Core\CommandLine\Command;
use ModulesGarden\ProxmoxAddon\Core\CommandLine\Hypervisor;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

/**
 * Description of MigrateSync
 *
 * @author Pawel Kopec <pawelk@modulesgardne.com>
 */
class MigrateSync extends Command
{

    use main\App\Services\BaseService;

    /** Command name
     * @var string
     */
    protected $name = 'migrateSync';

    /**
     * Command description
     * @var string
     */
    protected $description = '';

    /**
     * Command help text
     * @var string
     */
    protected $help = '';

    /**
     * Run your custom code
     * @param InputInterface $input
     * @param OutputInterface $output
     * @return int|null|void
     */
    protected function process(InputInterface $input, OutputInterface $output, SymfonyStyle $io)
    {
        $io->title('Synchronize migrate: Starting');
        if (!function_exists('ModuleBuildParams'))
        {
            require_once ROOTDIR . DIRECTORY_SEPARATOR . 'includes' . DIRECTORY_SEPARATOR . "modulefunctions.php";
        }
        //Get Hostings
        $h        = (new main\Core\Models\Whmcs\Hosting)->getTable();
        $s        = (new main\Core\Models\Whmcs\Server)->getTable();
        $hostings = main\Core\Models\Whmcs\Hosting::select("{$h}.*")
            ->rightJoin($s, "{$h}.server", '=', "{$s}.id")
            ->whereIn("{$h}.domainstatus", ["Active", "Suspended"])
            ->whereIn("{$s}.type", ["proxmoxVPS", "ProxmoxCloudVps"])
            ->orderBy("{$h}.server");
        $i        = 0;
        foreach ($hostings->get() as $hosting)
        {
            /* @var $hosting main\Core\Models\Whmcs\Hosting */
            $i++;
            $output->writeln(sprintf("Synchronize hosting: %s", $hosting->id));
            try
            {
                $params = \ModuleBuildParams($hosting->id);
                $this->setServerId($hosting->server);
                if ($this->getServer()->id != $this->getServerId())
                {
                    unset($this->server, $this->api);
                }
                $this->getApi()->setInstance();
                $resurceRepository = new proxmox\repository\ClusterResourcesRepository;
                if ($params['moduletype'] == "proxmoxVPS")
                {
                    if (!$params['customfields']['vmid'])
                    {
                        throw new \Exception("Custom Field \"vmid\" is empty");
                    }
                    if (!$params['customfields']['node'])
                    {
                        throw new \Exception("Custom Field \"node\" is empty");
                    }
                    if(!$this->isVpsCreated($params)){
                        continue;
                    }

                    foreach ($resurceRepository->fetch() as $resource)
                    {
                        if ($resource->getVmid() == $params['customfields']['vmid'] && $params['customfields']['node'] != $resource->getNode())
                        {
                            $output->writeln(sprintf("Hosting: %s, migration  has been found on VMID %s", $hosting->id, $params['customfields']['vmid']));
                            $f  = (new main\Core\Models\Whmcs\CustomField)->getTable();
                            $fv = (new main\Core\Models\Whmcs\CustomFieldValue())->getTable();
                            $cf = main\Core\Models\Whmcs\CustomFieldValue::rightJoin($f, "{$fv}.fieldid", '=', "{$f}.id")
                                ->where("{$f}.type", "product")
                                ->where("{$fv}.relid", $hosting->id)
                                ->where("{$f}.fieldname", "LIKE", "node%")
                                ->update(["value" => $resource->getNode()]);
                            break;
                        }
                    }
                }
                else
                {
                    if ($params['moduletype'] == "ProxmoxCloudVps")
                    {
                        $vservers = main\App\Models\VmModel::ofHostingId($hosting->id);
                        foreach ($vservers->get() as $vserver)
                        {
                            if(!$this->isVmCreated($vserver)){
                                continue;
                            }
                            foreach ($resurceRepository->fetch() as $resource)
                            {
                                if ($resource->getVmid() == $vserver->vmid && $vserver->node != $resource->getNode())
                                {
                                    $output->writeln(sprintf("Hosting: %s, migration  has been found on VMID %s", $hosting->id, $vserver->vmid));
                                    $vserver->node = $resource->getNode();
                                    $vserver->save();
                                    break;
                                }
                            }
                        }
                    }
                }
                $output->writeln(sprintf("Hosting: %s has been synchronized", $hosting->id));
            }
            catch (\Exception $ex)
            {
                if ($hosting)
                {
                    $io->error("Hosting Id #{$hosting->id}, " . $ex->getMessage());
                }
                else
                {
                    $io->error($ex->getMessage());
                }
            }
            (new Hypervisor($this->getName(), $input->getOptions()))
                ->ping();
        }
        $output->writeln("");
        $io->success([
            sprintf("Synchronize migrate: %s Entries Processed.", $i),
            "Synchronize migrate: Done"
        ]);
    }

    public function isVpsCreated($params)
    {
        $jobs = [
            CloneQemuJob::class,
            CreateQemuJob::class,
            CreateLxcJob::class,
            MigrateVmJob::class,
            RestoreVm::class,
            \ModulesGarden\ProxmoxAddon\App\Jobs\Vps\Reinstall\RestoreVm::class,
            UpgradeVmJob::class,
            CreateVmJob::class
        ];
        if(Job::waiting()->ofHostingId($params["serviceid"])->ofJobs($jobs)->count() > 0){
            return false;
        }else if (!$params['customfields']['vmid']){
            return false;
        }
        return true;
    }

    public function isVmCreated(   VmModel $vmModel)
    {
        $jobs = [
            \ModulesGarden\ProxmoxAddon\App\Jobs\Cloud\CloneQemuJob::class,
            \ModulesGarden\ProxmoxAddon\App\Jobs\Cloud\CreateQemuJob::class,
            \ModulesGarden\ProxmoxAddon\App\Jobs\Cloud\CreateLxcJob::class,
            \ModulesGarden\ProxmoxAddon\App\Jobs\Cloud\MigrateVmJob::class,
            \ModulesGarden\ProxmoxAddon\App\Jobs\Cloud\RestoreVm::class,
            \ModulesGarden\ProxmoxAddon\App\Jobs\Cloud\Reinstall\RestoreVm::class,
            \ModulesGarden\ProxmoxAddon\App\Jobs\Cloud\LoadBalancer\UpgradeVmJob::class,
            \ModulesGarden\ProxmoxAddon\App\Jobs\Cloud\Reinstall\CreateVmJob::class
        ];
        if (!$vmModel->vmid || $vmModel->vmid == 0 ){
            return false;
        }
        if(Job::waiting()->ofHostingId($vmModel->hosting_id)->ofJobs($jobs)->ofCustomId($vmModel->id)->count() > 0){
            return false;
        }

        return true;
    }
}
