<?php

use dokuwiki\Extension\SyntaxPlugin;

/**
 * DokuWiki Plugin yatp (Syntax Component)
 *
 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
 * @author Feralheart <dokuwiki@feralheart.dev>
 */
class syntax_plugin_yatp_template extends SyntaxPlugin
{
    /** @inheritDoc */
    public function getType()
    {
        return 'container';
    }

    /** @inheritDoc */
    public function getPType()
    {
        return 'normal';
    }

    /** @inheritDoc */
    public function getSort()
    {
        return 302;
    }

    /** @inheritDoc */
    public function connectTo($mode)
    {
        $this->Lexer->addSpecialPattern("{{template>.+?}}", $mode, 'plugin_yatp_template');
    }

    /** @inheritDoc */
    function handle($match, $state, $pos, Doku_Handler $handler) {
        global $ID;

        $helper = plugin_load('helper', 'yatp');

        $match = substr($match, 11, -2);                        // strip markup
        $replacers = preg_split('/(?<!\\\\)\|/', $match);        // Get the replacers
        $wikipage = array_shift($replacers);

        $replacers = $helper->messageReplacers($replacers);
        $template = $helper->getTemplateFile($wikipage);
        
        return array($template, $replacers);
    }

    /** @inheritDoc */
    public function render($mode, Doku_Renderer $renderer, $data)
    {
        global $ID;
        if ($mode !== 'xhtml') {
            return false;
        }

        $helper = plugin_load('helper', 'yatp');

        $templateName = $data[0];
        if(!$templateName) return false;

        $rawFile = $helper->getTemplate($templateName);
        if(!empty($data[1]['keys']) && !empty($data[1]['vals'])) {
            $rawFile = str_replace($data[1]['keys'], $data[1]['vals'], $rawFile);
        }

        // replace unmatched substitutions with "" or use DEFAULT_STR from data arguments if exists.
        $left_overs = '/'.BEGIN_REPLACE_DELIMITER.'.*'.END_REPLACE_DELIMITER.'/';

        if(!empty($data[1]['keys']) && !empty($data[1]['vals'])) {
            $def_key = array_search(BEGIN_REPLACE_DELIMITER."DEFAULT_STR".END_REPLACE_DELIMITER, $data[1]['keys']);
            $DEFAULT_STR = $def_key ? $data[1]['vals'][$def_key] : "";
            $rawFile = preg_replace($left_overs, $DEFAULT_STR, $rawFile);
        }

        $metadata = p_get_metadata($ID, 'relation');
        $existingRefs = isset($metadata['references']) ? $metadata['references'] : [];

        $instr = p_get_instructions($rawFile);

        foreach ($instr as $instruction) {
            list($cmd, $params) = $instruction;

            if ($cmd === 'internallink') {
                $linkID = cleanID($params[0]);
                if (!$linkID) continue;

                $existingRefs[$linkID] = page_exists($linkID);
            }
        }

        p_set_metadata($pageId, [
            'relation' => [
                'references' => $existingRefs
            ]
        ], true, true);
        
        // render the instructructions on the fly
        $info = ['cache' => false];
        $text = p_render('xhtml', $instr, $info);

        // remove toc, section edit buttons and category tags
        $patterns = array('!<div class="toc">.*?(</div>\n</div>)!s',
                          '#<!-- SECTION \[(\d*-\d*)\] -->#',
                          '!<div class="category">.*?</div>!s');
        $replace  = array('', '', '');
        $text = preg_replace($patterns, $replace, $text);

        // prevent caching to ensure the included page is always fresh
        $renderer->info['cache'] = FALSE;
        $renderer->info['depends']['pages'][] = $data[0];

        // embed the included page
        $renderer->doc .= '<div class="yatp">';
        $renderer->doc .= $text;
        $renderer->doc .= '</div>';

        return true;
    }
}
