<?php
/*
 * This class is used to manage cronjobs.
 * We use the PHP_SAPI to be sure to refuse to run on a webserver.
 * The command should be called like this :
 *     php index.php "/action"
 */
namespace Controller;

class Cron extends Controller
{
    public function beforeRoute($f3, $args)
    {
        parent::beforeRoute($f3, $args);
    }

    public function afterRoute($f3, $args)
    {
    }

    public function piplome($f3, $args)
    {
        // This method is used to generate a piplome. It might be called with an
        // id parameters, in which case we will ask to regenerate a specific piplome.
        if (!$f3->exists('SESSION.user')) {
            $f3->reroute('/login');
        }
        $logger = new \Log("/piplome.log");
        $ids = array();
        $db = $f3->get('DB');

        if (array_key_exists('id', $args)) {
            // Let's check if we can have a pdf
            $result = $db->query("SELECT dons.id as id, decimale, users.pseudo as nom, lang FROM dons LEFT JOIN users ON dons.user_id = users.id WHERE dons.status IN (1, 4, 101) AND dons.id='".\Utils::asl($args['id'])."'");
        } else {
            // We want to generate all piplomes which does not exists yet
            $result = $db->query("SELECT dons.id as id, decimale, users.pseudo as nom, lang FROM dons LEFT JOIN users ON dons.user_id = users.id WHERE pdf='' AND dons.status IN (1, 4, 101) LIMIT 100;");
        }

        $pdfs = [];
        foreach ($result->fetchAll(\PDO::FETCH_ASSOC) as $row) {
            $pdfs[] = $row;
        }

        // We do have our IDs
        // We need to create a PDF
        $lock = @fopen("../tmp/piplomes.lock", "ab");
        if ($lock) {
            flock($lock, LOCK_EX);
            foreach ($pdfs as $pdf) {
                $logger->write("Generating piplome id:".$pdf['id']."");
                if (!$pdf['decimale'] or $pdf['decimale'] == 0) {
                    // We need to get a pi decimals
                    do {
                        $decimale = rand(10, 200000);
                        $logger->write("Trying if $decimale is free");
                        $result = $db->query("SELECT id FROM dons WHERE decimale='".\Utils::asl($decimale)."';");
                        $tmp = $result->fetchAll(\PDO::FETCH_COLUMN, 'id');
                    } while ($tmp);
                    $logger->write("Found a decimal of pi: ".$decimale."");
                    $pdf['decimale'] = $decimale;
                }

                // We need a tmp unique filename
                $pdf['hash'] = $pdf['id']."_".substr(md5("Enter the Darquenette".$pdf['id']), 10, 16);
                $logger->write("Calculated hash: ".$pdf['hash']."");

                // Let's trash the garbage
                foreach (array('tex', 'aux', 'pdf', 'log') as $ext) {
                    @unlink(dirname(__FILE__)."/../../tmp/pplome.".$ext);
                }

                // We now have only fr or en templates
                if ($pdf['lang'] == 'fr') {
                    $pdf['lang'] = 'fr_FR';
                }
                if ($pdf['lang'] != 'fr_FR') {
                    $pdf['lang'] = 'en_US';
                }
                $logger->write("Language is ".$pdf['lang']."");

                $template = file_get_contents(dirname(__FILE__)."/../../locales/".$pdf['lang']."/LC_MESSAGES/plome.tex");

                // We will open the pi-decimals file
                $pi = fopen(dirname(__FILE__)."/../../www/static/pi-billion/pi-billion.txt", "rb");

                if (!$pi) {
                    $logger->write("FATAL: Can't open decimals");
                    exit();
                }

                // Let's get the specific set of decimals we want
                fseek($pi, 1000 * $pdf['decimale']);
                $decimales = "";
                for ($i = 0; $i < 10; $i++) {
                    $dec = fgets($pi, 100);
                    $decimales .= "\x{".$dec."}\n";
                }
                fclose($pi);

                $pdf['nom'] = \Utils::clean_encoding(\Utils::sanitize_piplomes($pdf['nom']));
                $logger->write("PDF File will be ". $pdf['hash']);
                $logger->write("decimales: ".$decimales);

                // Let's replace the templates with values
                file_put_contents(
                    dirname(__FILE__)."/../../tmp/pplome.tex",
                    str_replace(
                        "%%DECIMALES%%",
                        $decimales,
                        str_replace(
                        "%%NOM%%",
                        $pdf['nom'],
                        str_replace(
                        "%%MILLIER%%",
                        $pdf['decimale'],
                        $template
                        )
                        )
                    )
                );

                // Let's create the pdf from the template
                $logger->write("Building the pdf from the tex template");
                $command = 'TEXINPUTS='.dirname(__FILE__).'/../../tex/:$TEXINPUTS ';

                // We need to set an env variable first
                putenv('TEXINPUTS='.dirname(__FILE__).'/../../tex:'.getenv('TEXINPUTS'));
                $command .= '/usr/bin/pdflatex ';
                $command .= '-output-directory='.dirname(__FILE__)."/../../tmp ";
                $command .= dirname(__FILE__)."/../../tmp/pplome.tex";
                $logger->write($command);
                exec($command, $output, $return);
                foreach ($output as $line) {
                    $logger->write($line);
                }

                if ($return != 0) {
                    $logger->write("Error");
                    $db->query("UPDATE dons SET pdf='Error $return' WHERE id='".$pdf['id']."';");
                    continue;
                }
                $logger->write("PDF created");

                // Move the pdf to its position
                @unlink(PIPLOME_PATH . $pdf['hash'] .".pdf");
                $logger->write("Moving pdf to ".PIPLOME_PATH.$pdf['hash'].".pdf");
                @rename(dirname(__FILE__)."/../../tmp/pplome.pdf", PIPLOME_PATH . $pdf['hash'] . ".pdf");
                
                // Let's trash the garbage
                foreach (array('tex', 'aux', 'pdf', 'log') as $ext) {
                    @unlink(dirname(__FILE__)."/../../tmp/pplome.".$ext);
                }

                // Saving the pathin database
                $db->query("UPDATE dons SET pdf='".$pdf['hash']."', decimale='".$pdf['decimale']."' WHERE id='".$pdf['id']."';");
            }

            // Generating all the pdf, freeing the locks
            flock($lock, LOCK_UN);
            fclose($lock);
            @unlink("/tmp/generate.lock");
        } else {
            //Error
            $logger->write("Can't get access to lock.");
        }
        $logger->write("Generation finished");

        if (array_key_exists('id', $args) && php_sapi_name() != 'cli') {
            // We will send the PDF file to the browser
            $result = $db->query("SELECT dons.id as id,
                    decimale,
                    users.pseudo as nom,
                    lang,
                    pdf
                FROM dons
                    LEFT JOIN users ON dons.user_id = users.id
                WHERE dons.status IN (1, 4, 101)
                    AND dons.id='".\Utils::asl($args['id'])."'");
            $pdf = $result->fetch(\PDO::FETCH_ASSOC);
            $fp = fopen(PIPLOME_PATH . $pdf['pdf'] .".pdf", "rb");
            if ($fp) {
                $fsize = filesize(PIPLOME_PATH . $pdf['pdf'] .".pdf");
                header("Content-Type: application/pdf");
                header("Content-Disposition: attachment; filename=\"".$pdf['pdf'].".pdf\"");
                header("Content-Length: $fsize");
                while (!feof($fp)) {
                    $buffer = fread($fp, 2048);
                    echo $buffer;
                }
                fclose($fp);
            } else {
                $f3->reroute('/perso');
            }
        }
    }
}