<?php


namespace ModulesGarden\ProxmoxAddon\App\Cron;


use ModulesGarden\ProxmoxAddon\App\Jobs\Vps\SnapshotVmJob;
use ModulesGarden\ProxmoxAddon\App\Models\Job;
use ModulesGarden\ProxmoxAddon\App\Models\ProductConfiguration;
use ModulesGarden\ProxmoxAddon\App\Models\SnapshotJob;
use ModulesGarden\ProxmoxAddon\App\Models\Whmcs\Hosting;
use ModulesGarden\ProxmoxAddon\App\Services\ApiService;
use ModulesGarden\ProxmoxAddon\App\Services\Vps\ProductService;
use ModulesGarden\ProxmoxAddon\Core\CommandLine\Command;
use ModulesGarden\ProxmoxAddon\Core\UI\Traits\WhmcsParams;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use function ModulesGarden\ProxmoxAddon\Core\Helper\queue;

class Snapshots extends Command
{
    use WhmcsParams;
    use ProductService;
    use ApiService;

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

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

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

    /**
     * @param InputInterface $input
     * @param OutputInterface $output
     * @param SymfonyStyle $io
     * @throws \Exception
     * @query daily SELECT *, DATE(`updated_at`) as t FROM `ProxmoxAddon_SnapshotJob` where `period` = 'daily' and TIMESTAMP(`start_time`) < TIMESTAMP(NOW()) and TIMESTAMP(updated_at) < TIMESTAMP(`start_time`) or ( `period` = 'daily' AND `start_time` is NULL AND DATE(`updated_at`) != DATE(NOW()) )
     * @query hourly SELECT *, DATE(`updated_at`) as t FROM `ProxmoxAddon_SnapshotJob` where `period` = 'hourly' and TIMESTAMP(NOW()) >= TIMESTAMP( DATE_ADD(updated_at, INTERVAL `run_every` HOUR ))
     */
    protected function process(InputInterface $input, OutputInterface $output, SymfonyStyle $io)
    {
        $io->title('Snapshots schedule: Starting');
        $productIds = ProductConfiguration::ofSetting('permissionSnapshotJob')
            ->where("value", "not like", '\"\"')
            ->pluck("product_id")
            ->all();
        if (empty($productIds))
        {
            $io->error("Scheduled Snapshot Jobs is not configured");
            return;
        }
        $h        = (new Hosting())->getTable();
        $sj =  (new SnapshotJob())->getTable();
        $entities = SnapshotJob::select("{$sj}.*")
            ->leftJoin($h, "{$h}.id", '=', "{$sj}.hosting_id")
            ->whereRaw("{$sj}.period = 'daily' 
                        AND TIMESTAMP({$sj}.start_time) < TIMESTAMP(NOW()) 
                        AND TIMESTAMP({$sj}.updated_at) < TIMESTAMP({$sj}.start_time)
                        OR ( {$sj}.period = 'daily' 
                             AND {$sj}.start_time IS NULL 
                             AND DATE({$sj}.updated_at) != DATE(NOW()) 
                             )
                        OR (
                            {$sj}.period = 'hourly' 
                            AND  TIMESTAMP(NOW()) >= TIMESTAMP( DATE_ADD({$sj}.updated_at, INTERVAL {$sj}.run_every HOUR ))
                            )
                        ")
            ->where("{$h}.domainstatus", "Active")
            ->whereIn("{$h}.packageid", $productIds);
        $i        = 0;
        /**
         * DAYName(NOW())        Friday
         * @var  SnapshotJob $entity
         */
        foreach ($entities->get() as $entity)
        {

            try
            {
                $now = new \DateTime();
                $today = $now->format("l");
                if($entity->period == "daily" && ( $entity->days && !in_array($today, $entity->days) ) ){
                    continue;
                }
                $i++;
                $output->writeln(sprintf("Synchronize snapshot job #%s (Hosting ID %s)",$entity->id, $entity->hosting_id));
                //cloud
                if($entity->vm_id){
                    $jobClass = \ModulesGarden\ProxmoxAddon\App\Jobs\Cloud\SnapshotVmJob::class;
                }else{//vps
                    $jobClass = SnapshotVmJob::class;
                }
                $query = Job::waiting()
                             ->ofHostingId($entity->hosting_id)
                            ->ofJob($jobClass);
                if($entity->vm_id){
                    $query->ofCustomId($entity->vm_id);
                }
                if(!$query->count()){
                    $job=["snapshotJobId"=> $entity->id];
                    queue($jobClass, $job, null, "hosting", $entity->hosting_id, $entity->vm_id);
                    $entity->update(['updated_at' => date("Y-m-d H:i:s")]);
                    $output->writeln(sprintf("Snapshot job #%s has been synchronized", $entity->id));
                }
            }catch (\Exception $ex)
            {
                $io->error( $ex->getMessage());
            }
        }
        $output->writeln("");
        $io->success([
            sprintf("Synchronize snapshots schedule: %s Entries Processed.", $i),
            "Snapshots schedule: Done"
        ]);
    }

}