<?php

use KupShop\KupShopBundle\Util\Locale\WarningGettextTranslator;

/**
 * {t}{/t} compile tags for Smarty WITH translations (SmartyML).
 */
class Smarty_Compiler_T extends Smarty_Internal_CompileBase
{
    public $optional_attributes = ['_any'];

    /**
     * @var Smarty_Internal_SmartyTemplateCompiler
     */
    private $compiler;

    /**
     * @param $compiler Smarty_Internal_SmartyTemplateCompiler
     *
     * @return string
     */
    public function compile($args, $compiler)
    {
        $_args = $this->getAttributes($compiler, $args);
        $this->compiler = $compiler;

        $lexer = $compiler->parser->lex;

        $term = '';

        $line = $lexer->line;
        $file = $compiler->template->template_resource;

        if ($lexer->value == '}') {
            $lexer->yylex();
        }

        $counter = 0;
        do {
            $term .= $lexer->value;
            $lexer->yylex();
            if ($counter++ > 1000) {
                throw new Exception("Nemůžu najít konec překladového tagu začínajícího {$file}:{$line}");
            }
        } while ($lexer->value != '{/t}');

        unset($_args['1']);

        return $this->translate($term, $_args);
    }

    public function export_params($params, $except = [])
    {
        return '['.
            join(',',
                array_map(
                    function ($name) use ($params) {
                        return "'{$name}' => {$params[$name]}";
                    },
                    array_diff(array_keys($params), $except)
                )
            )
            .']';
    }

    public function translate($text, $params)
    {
        if (empty($text)) {
            return $text;
        }

        $text = preg_replace('/\s+/sm', ' ', $text);

        $defaults = [
            'escape' => 'html',
            'domain' => null,
        ];

        $params = array_merge($defaults, $params);

        $params['escape'] = trim($params['escape'], "'");

        /** @var WarningGettextTranslator $translator */
        $translator = $this->compiler->smarty->loadTranslations();

        // plural form
        if (isset($params['count']) || isset($params['plural'])) {
            return $this->translate_plural($params, $text, $translator);
        }

        // use specified textdomain if available
        if (!is_null($params['domain'])) {
            $text = $translator->dgettext($params['domain'], $text);
        } else {
            $text = $translator->gettext($text);
        }

        $text = static::escape($text, $params['escape']);

        // Can do partial static translation if parameters are present
        if (array_diff(array_keys($params), ['nocache', 'domain', 'count', 'plural', 'plural5', 'escape'])) {
            $params = $this->export_params($params, ['nocache', 'domain', 'count', 'plural', 'plural5', 'escape']);
            $text = str_replace("'", "\\'", $text);

            return "<?php echo \KupShop\KupShopBundle\Util\StringUtil::replacePlaceholders('{$text}', {$params}); ?>";
        }

        return $text;
    }

    public function translate_plural($params, $original, WarningGettextTranslator $translator)
    {
        $reflection = new ReflectionObject($translator);
        // metoda na fixnuti ternary ifu
        $fixTerseIfs = $reflection->getMethod('fixTerseIfs');
        $fixTerseIfs->setAccessible(true);

        [$translations, $expression] = $translator->getPluralTranslateData($params['domain'], null, $original);

        // fixnout ternary ify
        $expression = $fixTerseIfs->invoke($translator, $expression);
        // upravit expressionu
        $expression = trim(str_replace('$n', $params['count'], $expression), 'return; ');
        $expression = !empty($expression) ? '('.$expression.')' : 'null';

        $params['escape'] = "'{$params['escape']}'";
        $params = $this->export_params($params, ['nocache', 'domain', 'count', 'plural', 'plural5']);

        return "<?php echo Smarty_Compiler_T::translate_plural_runtime({$this->export_params($translations)}, {$params}, {$expression});  ?>";
    }

    public static function translate_plural_runtime($translation, $params, $key)
    {
        $text = reset($translation);
        if (isset($translation[$key]) && $translation[$key] !== '') {
            $text = $translation[$key];
        }

        if (!empty($params)) {
            $text = \KupShop\KupShopBundle\Util\StringUtil::replacePlaceholders($text, $params);
        }

        return static::escape($text, $params['escape']);
    }

    private static function escape($text, $mode)
    {
        switch ($mode) {
            case 'html':
                return nl2br(htmlspecialchars($text));
            case 'javascript':
            case 'js':
                // javascript escape
                return strtr($text, ['\\' => '\\\\', "'" => "\\'", '"' => '\\"', "\r" => '\\r', "\n" => '\\n', '</' => '<\/']);
            case 'url':
                // url escape
                return urlencode($text);
        }

        return $text;
    }
}

class Smarty_Compiler_Tclose extends Smarty_Internal_CompileBase
{
    public $required_attributes = [];
    public $optional_attributes = [];
    public $shorttag_order = [];

    public function compile($args, $compiler)
    {
        return '';
    }
}
