<?php
/**
 * Action module for yatp plugin: Handles backlink indexing at page indexing time
 */

use dokuwiki\Extension\ActionPlugin;
use dokuwiki\Extension\EventHandler;
use dokuwiki\Indexer\Indexer;

require_once(DOKU_INC . 'inc/indexer.php');

class action_plugin_yatp_indexer extends ActionPlugin
{
    public function register(EventHandler $controller)
    {
        $controller->register_hook('INDEXER_PAGE_ADD', 'BEFORE', $this, 'handle_indexer', ['priority' => 100]);
    }

    public function handle_indexer(Doku_Event $event, $param)
    {
        $pageId = $event->data['page'];
        $helper = plugin_load('helper', 'yatp');
        $text = rawWiki($pageId);

        if (!preg_match_all('/\{\{template>([^#|}]+)(?:\|([^#}]*))?(?:#([^\}]+))?\}\}/', $text, $matches, PREG_SET_ORDER)) {
            return;
        }

        p_set_metadata($pageId, [
            'relation' => [
                'references' => []
            ]
        ], false, true);

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

        foreach ($matches as $match) {
            $templateName = $match[1];
            $templateId = $helper->getTemplateFile($templateName);
            if (!$templateId) continue;
            
            $rawFile = $helper->getTemplate($templateId);
            if (!$rawFile) continue;

            $replacers = $helper->messageReplacers(preg_split('/(?<!\\\\)\|/', $match[2]));

            if(!empty($replacers['keys']) && !empty($replacers['vals'])) {
                $rawFile = str_replace($replacers['keys'], $replacers['vals'], $rawFile);
            }

            $instr = p_get_instructions($rawFile);

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

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

                    if (!$linkID) continue;

                    $existingRefs[$linkID] = page_exists($linkID);
                }
            }
        }
        p_set_metadata($pageId, [
            'relation' => [
                'references' => $existingRefs
            ]
        ], true, true);
        idx_get_indexer()->addMetaKeys($pageId, 'relation references', $existingRefs);
    }
}
