<?php

namespace Miruni\Merge_Syntax;

if (!defined('ABSPATH')) {
    exit; // Exit if accessed directly
}

use Miruni\Merge_Syntax\Miruni_Merge_SyntaxOperation;
use Miruni\Merge_Syntax\Miruni_Merge_Action;

/**
 * Class Miruni_Merge_Syntax_Parser
 *
 * This class is responsible for parsing merge syntax in the Miruni plugin.
 * Merge syntax will follow the following pattern: {{MIRUNI:<action> <arg_key>=<arg_value> ...}}
 * For example = {{MIRUNI:ATTACHMENT_URL attachment_id=1}}
 * 
 * We will need to parse any string and return a list of operation objects. The operation object will have its own class.
 */
class Miruni_Merge_Syntax_Parser
{

    /**
     * Parse a string and return an array of Miruni_Merge_SyntaxOperation objects
     *
     * @param string $text
     * @return Miruni_Merge_SyntaxOperation[]
     */
    public static function parse(string $text): array
    {
        $results = [];

        // Match {{MIRUNI:ACTION ...args...}}
        $pattern = '/\{\{\s*MIRUNI:([A-Z_]+)([^}]*)\}\}/';
        if (!preg_match_all($pattern, $text, $matches, PREG_SET_ORDER)) {
            return $results;
        }

        foreach ($matches as $m) {
            $action = $m[1];
            $argString = trim($m[2]);

            $args = [];

            if ($argString !== '') {
                // Match key=value where value can be double-quoted, single-quoted, or unquoted (no spaces)
                $argPattern = <<<'PAT'
    /([a-zA-Z0-9_]+)=("(?:[^"\\\\]|\\\\.)*"|'(?:(?:[^'\\\\]|\\\\.)*)'|[^\s]+)/
    PAT;
                if (preg_match_all($argPattern, $argString, $argMatches, PREG_SET_ORDER)) {
                    foreach ($argMatches as $am) {
                        $key = $am[1];
                        $val = $am[2];

                        // Strip surrounding quotes if present and unescape
                        if ((str_starts_with($val, '"') && str_ends_with($val, '"')) || (str_starts_with($val, "'") && str_ends_with($val, "'"))) {
                            $val = substr($val, 1, -1);
                            $val = stripcslashes($val);
                        }

                        $args[$key] = $val;
                    }
                }
            }

            try {
                $op = new Miruni_Merge_SyntaxOperation($action, $args);
                $results[] = $op;
            } catch (\ValueError $e) {
                // Unknown action - skip
                continue;
            }
        }

        return $results;
    }

}