<?php

namespace Cadoles\CronBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;


use Cadoles\CronBundle\Entity\Cron;
use Cadoles\CronBundle\Form\CronType;

class CronController extends Controller
{
    private $labelentity="CadolesCronBundle:Cron";
    private $routeprimary="cadoles_cron_config";

    public function listAction()
    {
        return $this->render($this->labelentity.':list.html.twig',[
            'useheader'         => true,
            'usemenu'           => false,
            'usesidebar'        => true,              
        ]);
    }

    public function ajaxlistAction(Request $request)
    {
        // S'assurer que c'est un appel ajax
        if (!$request->isXmlHttpRequest()) {
            return new JsonResponse(array('message' => 'Interdit'), 400);
        }
        
        $em = $this->getDoctrine()->getManager();

        $start=$request->query->get('start');
        $length= $request->query->get('length');
        $search= $request->query->get('search');
        $draw= $request->query->get('draw');
        $order= $request->query->get('order');
      
        // Query de base
        $qbase=$em->createQueryBuilder()->from($this->labelentity,'table');
        $qsearch=$qbase->Where('table.id LIKE :value')
                       ->orWhere('table.command LIKE :value')
                       ->orWhere('table.jsonargument LIKE :value')
                       ->andWhere('table.repeatcall=0 OR (table.statut!=2 AND table.repeatcall>0)')
                       ->setParameter("value", "%".$search["value"]."%");

        // Nombre total d'enregistrement
        $total = $qbase->select('COUNT(table)')->getQuery()->getSingleScalarResult();

        // Nombre d'enregistrement filtré
        if($search["value"]=="")
            $totalf = $total;
        else {
            $totalf= $qsearch->select('COUNT(table)')->getQuery()->getSingleScalarResult();
        }

        // Parcours des Enregistrement
        if($search["value"]=="")
            $qb = $qbase->select('table');
        else
            $qb = $qsearch->select('table');

        // Order
        switch($order[0]["column"]) {
            case 1 : 
            $qb->orderBy('table.nextexecdate',$order[0]["dir"]);
            break;            
            case 2 : 
            $qb->orderBy('table.command',$order[0]["dir"]);
            break;
            case 3 : 
            $qb->orderBy('table.description',$order[0]["dir"]);
            break;        
            case 4 : 
            $qb->orderBy('table.statut',$order[0]["dir"]);
            break;     
        }

        // Execution de la requete d'affichage
        $datas=$qb->setFirstResult($start)->setMaxResults($length)->getQuery()->getResult();

        // Construction du tableau de retour
        $output = array(
            'draw' => $draw,
            'recordsFiltered' => $totalf,
            'recordsTotal' => $total,
            'data' => array(),
        );
        foreach($datas as $data) {
            $action = "<a href='".$this->generateUrl($this->routeprimary.'_update', array('id'=>$data->getId()))."' title='Modifier'><i class='fa fa-file fa-fw fa-2x'></i></a>";
            $action.= "<a href='".$this->generateUrl($this->routeprimary.'_exec', array('id'=>$data->getId()))."' title='Exécuter'><i class='fa fa-play fa-fw fa-2x'></i></a>";

            $nextexec=($data->getNextexecdate()==null?"":$data->getNextexecdate()->format("d/m/Y H:i:s"));
            if($data->getRepeatCall()>0 AND $data->getRepeatCall()<=$data->getRepeatExec())
                $nextexec="Déjà rejoué ".$data->getRepeatExec()." fois";
            
            array_push($output["data"],array($action,$nextexec,$data->getCommand(),$data->getDescription(),$data->getStatutLabel()));
        }

        // Retour
        return new Response(json_encode($output), 200);
    }  

    public function updateAction(Request $request, $id)
    {
        $em = $this->getDoctrine()->getManager();
        $entity = $em->getRepository($this->labelentity)->find($id);

        if (!$entity) {
            throw $this->createNotFoundException('Unable to find entity.');
        }
        
        $form = $this->createForm(CronType::class, $entity, ['method' => 'POST']);
        $form->handleRequest($request);

        if ($form->isValid()) {
            $em->persist($entity);
            $em->flush();

            return $this->redirect($this->generateUrl($this->routeprimary));
        }

        return $this->render($this->labelentity.':edit.html.twig', [
            'useheader'         => true,
            'usemenu'           => false,
            'usesidebar'        => true,              
            'entity'            => $entity,
            'form'              => $form->createView(),
        ]);
    }

    public function execAction(Request $request, $id)
    {
        set_time_limit(0);
        
        $em = $this->getDoctrine()->getManager();
        $entity = $em->getRepository($this->labelentity)->find($id);

        if (!$entity) {
            throw $this->createNotFoundException('Unable to find entity.');
        }

        $kernel = $this->get('kernel');
        $application = new Application($kernel);
        $application->setAutoExit(false);
        $command = $application->find($entity->getCommand());
        $jsonparameter=json_decode($entity->getJsonargument(),true);
        $parameter = ($jsonparameter?new ArrayInput($jsonparameter):new ArrayInput([]));


        $output = new BufferedOutput(OutputInterface::VERBOSITY_NORMAL,false);
        $command->run($parameter, $output);
        $content = $output->fetch();

        return $this->render('CadolesCoreBundle:Core:command.html.twig', [
            'useheader'         => true,
            'usemenu'           => false,
            'usesidebar'        => true,               
            "title"             => $entity->getDescription(),
            "return_path"       =>"cadoles_cron_config",
            "content"           =>$content
        ]);
    }

    public function cronexecAction() {
        return $this->render('CadolesCronBundle:Cron:exec.html.twig', [
            'useheader'         => true,
            'usemenu'           => false,
            'usesidebar'        => true,               
        ]);
    }

    public function cronexecreadAction() {
        $kernel = $this->get('kernel');
        $path = $this->get('kernel')->getRootDir() . '/../var/logs/exec.log';
        $content = file_get_contents($path);

        $output["data"]=$content;
        return new Response(json_encode($content), 200);
    }

    public function logAction()
    {
        return $this->render('CadolesCronBundle:Cron:logs.html.twig', [
            'useheader'         => true,
            'usemenu'           => false,
            'usesidebar'        => true
        ]);
    }    

    public function getlogAction(Request $request, $id)
    {
        $kernel = $this->get('kernel');
        if($id=="dump")
            $file = $this->get('kernel')->getRootDir() . '/../var/logs/ninegate.sql';
        else
            $file = $this->get('kernel')->getRootDir() . '/../var/logs/'.$id.'.log';
        
        $response = new BinaryFileResponse($file);
        $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT);
        return $response;
    }    
}
