<?php

use Twig\Error\LoaderError;
use Twig\Source;

/**
 * Charge un template Twig depuis la table template d'openADS
 *
 * TODO : en attendant la modification listée dans @getCacheKey(), la même limitation
 * s'applique que sur \Twig\Loader\ArrayLoader :
 * When using this loader with a cache mechanism, you should know that a new cache
 * key is generated each time a template content "changes" (the cache key being the
 * source code of the template). If you don't want to see your cache grows out of
 * control, you need to take care of clearing the old cache file by yourself.
 */
final class DatabaseTemplateLoader implements \Twig\Loader\LoaderInterface
{
    private array $templates_cache = [];

    public function __construct(
        private utils $f,
    ) {
    }

    /**
     * On charge le template depuis la base de données, 
     * et on le met en cache localement pour ne pas interroger plusieurs fois
     * la BBD dans un seul loader
     */
    private function getTemplate(string $tpl_id): ?\template
    {
        return $this->templates_cache[$tpl_id] ??= $this->f->findObjectById(\template::class, $tpl_id);
    }

    // -----------------------------------------------------------------------------
    

    public function getSourceContext(string $name): Source
    {
        $template = $this->getTemplate($name);
        if ($template === null) {
            throw new LoaderError(\sprintf('Template "%s" is not defined.', $name));
        }

        return new Source($template->getVal('code'), $name);
    }

    public function exists(string $name): bool
    {
        return $this->getTemplate($name) !== null;
    }

    public function getCacheKey(string $name): string
    {
        $template = $this->getTemplate($name);

        if ($template === null) {
            throw new LoaderError(\sprintf('Template "%s" is not defined.', $name));
        }

        // TODO : actuellemement, on utilise le contenu complet du template comme clé de cache
        // Ultérieurement, il faudrait utiliser la clé primaire seule comme clé de cache
        // et de se baser sur une (nouvelle) colonne avec la date de dernière modification
        // pour la comparaison dans ->isFresh()

        return $template->getVal($template->clePrimaire).':'.$template->getVal('code');
    }

    public function isFresh(string $name, int $time): bool
    {
        $template = $this->getTemplate($name);
        if ($template === null) {
            throw new LoaderError(\sprintf('Template "%s" is not defined.', $name));
        }

        return true;
    }
}
