<?php

/**
 * @method get(string $string, Closure $param)
 */
class urlRouter {

    var $availableMethods = ['get', 'post', 'put', 'delete', 'patch', 'options'];
    var $requestURI = '';
    var $requestMethod = '';

    function __construct($urlPrefix = '') {
        $requestURI = $_SERVER['REQUEST_URI'];
        $requestURI = parse_url($requestURI, PHP_URL_PATH);
        if ($urlPrefix != '') {
            $requestURI = preg_replace('/^(\/|)'.preg_quote($urlPrefix, '/').'/', '', $requestURI);
        }

        $this->requestURI = $requestURI;
        $this->requestMethod = strtolower($_SERVER['REQUEST_METHOD']);
    }

    /**
     * @throws Exception ошибки при вызове роутера
     */
    public function __call($method, $arguments) {
        $method = strtolower($method);
        if (!in_array($method, $this->availableMethods)) {
            throw new Exception("Router error: method not found", 1);
        }

        if ($method != $this->requestMethod) {
            return false;
        }
        
        if (count($arguments) > 2 ) {
            throw new Exception("Router error: arguments too long", 1);
        }

        if (count($arguments) < 1 ) {
            throw new Exception("Router error: no arguments", 1);
        }

        $url = $arguments[0];
        $callback = $arguments[1];

        if (!is_callable($callback)) {
            throw new Exception("Router error: function not callable", 1);
        }

        // Тестируем URL на соответствие строки
        $url_mask = preg_quote($url, '/');
        $url_mask = preg_replace('/\\\{.*?\\\}/', '(.*?)', $url_mask);

        if (preg_match('/^'.$url_mask.'$/', $this->requestURI, $matches)) {
            unset($matches[0]);
            echo call_user_func_array($callback, $matches);
            die();
        }
        return true;
    }
 
 }

?>