<?php

namespace DeliciousBrains\WP_Offload_Media\Gcp\Rize;

use DeliciousBrains\WP_Offload_Media\Gcp\Rize\UriTemplate\Parser;
/**
 * URI Template
 */
class UriTemplate
{
    /**
     * @var Parser
     */
    protected $parser, $parsed = array(), $base_uri, $params = array();
    public function __construct($base_uri = '', $params = array(), Parser $parser = null)
    {
        $this->base_uri = $base_uri;
        $this->params = $params;
        $this->parser = $parser ?: $this->createNodeParser();
    }
    /**
     * Expands URI Template
     *
     * @param string $uri  URI Template
     * @param array  $params        URI Template's parameters
     * @return string
     */
    public function expand($uri, $params = array())
    {
        $params += $this->params;
        $uri = $this->base_uri . $uri;
        $result = array();
        // quick check
        if (($start = \strpos($uri, '{')) === \false) {
            return $uri;
        }
        $parser = $this->parser;
        $nodes = $parser->parse($uri);
        foreach ($nodes as $node) {
            $result[] = $node->expand($parser, $params);
        }
        return \implode('', $result);
    }
    /**
     * Extracts variables from URI
     *
     * @param  string $template
     * @param  string $uri
     * @param  bool   $strict  This will perform a full match
     * @return null|array params or null if not match and $strict is true
     */
    public function extract($template, $uri, $strict = \false)
    {
        $params = array();
        $nodes = $this->parser->parse($template);
        # PHP 8.1.0RC4-dev still throws deprecation warning for `strlen`.
        # $uri    = (string) $uri;
        foreach ($nodes as $node) {
            // if strict is given, and there's no remaining uri just return null
            if ($strict && !\strlen((string) $uri)) {
                return null;
            }
            // uri'll be truncated from the start when a match is found
            $match = $node->match($this->parser, $uri, $params, $strict);
            list($uri, $params) = $match;
        }
        // if there's remaining $uri, matching is failed
        if ($strict && \strlen((string) $uri)) {
            return null;
        }
        return $params;
    }
    public function getParser()
    {
        return $this->parser;
    }
    protected function createNodeParser()
    {
        static $parser;
        if ($parser) {
            return $parser;
        }
        return $parser = new Parser();
    }
}
