<?php

namespace MDirectorNewsletter\includes;

use Twig\Environment;
use Twig\Loader\FilesystemLoader;
use Twig\Markup;
use Twig\TwigFilter;

class Mdirector_Newsletter_Twig
{
    // Twig System
    const ADMIN_TEMPLATE_PATH = MDIRECTOR_NEWSLETTER_PLUGIN_DIR
    . 'admin/templates/';
    const ADMIN_TEMPLATE = 'admin-template.twig';
    const USER_TEMPLATE = 'template.twig';
    const TWIG_AUTO_RELOAD = true;
    const TWIG_AUTO_ESCAPE = 'html';

    public function translate( $string ) {
        $translations = get_translations_for_domain( 'emblue-newsletter' );
        return new Markup( $translations->translate( $string ), 'UTF-8' );
    }

    public function shortCode($shortCode)
    {
        return do_shortcode($shortCode);
    }

    private function getEnvironmentOptions()
    {
        return [
            'cache' => $this->getCachePath(),
            'auto_reload' => self::TWIG_AUTO_RELOAD,
            'autoescape' => self::TWIG_AUTO_ESCAPE
        ];
    }

    /**
     * Path for Twig's compiled-template cache, located in the WordPress uploads
     * directory (never inside the plugin folder, which may be read-only and would
     * ship generated files). Returns false to disable caching if the directory
     * cannot be created.
     *
     * @return string|false
     */
    public function getCachePath()
    {
        $uploads = wp_upload_dir();

        if ( ! empty( $uploads['error'] ) ) {
            return false;
        }

        $path = trailingslashit( $uploads['basedir'] ) . 'emblue-newsletter/twig-cache';

        // Disable caching (rather than fatally failing) if the directory can't
        // be created or written to — e.g. read-only or wrongly-owned uploads.
        if ( ! wp_mkdir_p( $path ) || ! wp_is_writable( $path ) ) {
            return false;
        }

        return $path;
    }

    /**
     * @return \Twig\TemplateWrapper
     * @throws \\Twig\Error\LoaderError
     * @throws \\Twig\Error\RuntimeError
     * @throws \\Twig\Error\SyntaxError
     */
    public function initAdminTemplate()
    {
        return $this->initAdminTwig()->load(self::ADMIN_TEMPLATE);
    }

    /**
     * @return \Twig\Environment
     */
    private function initAdminTwig()
    {
        $loader = new FilesystemLoader(self::ADMIN_TEMPLATE_PATH);
        $twigEnvironment =
            new Environment($loader, $this->getEnvironmentOptions());

        $this->initTranslations($twigEnvironment);

        return $twigEnvironment;
    }

    /**
     * @param \Twig\Environment $twigInstance
     */
    private function initTranslations(\Twig\Environment $twigInstance)
    {
        $filter = new TwigFilter('translate', [$this, 'translate']);
        $twigInstance->addFilter($filter);
    }

    /**
     * @param \Twig\Environment $twigInstance
     */
    private function initShortCodes(\Twig\Environment $twigInstance)
    {
        $filter = new TwigFilter('do_shortcode', [$this, 'shortCode']);
        $twigInstance->addFilter($filter);
    }

    /**
     * @param $templateData
     *
     * @return \Twig\Environment
     */
    public function initUserTemplate($templateData)
    {
        return $this->initUserTwig($templateData['templatePath']);
    }

    /**
     * @param $templatePath
     *
     * @return \Twig\Environment
     */
    private function initUserTwig($templatePath)
    {
        $loader = new FilesystemLoader($templatePath);
        $twigEnvironment =
            new Environment($loader, $this->getEnvironmentOptions());
        $this->initShortCodes($twigEnvironment);

        return $twigEnvironment;
    }
}
