<?php

declare(strict_types=1);

namespace Apexl\Io\Routing;

use Slim\Interfaces\RouteGroupInterface;
use Slim\Interfaces\RouteInterface;
use Slim\Routing\RouteCollectorProxy;

/**
 * The proxy handed to a group's closure, which checks patterns before concatenating them.
 *
 * The collector cannot do this itself: by the time a grouped route reaches it, the group
 * prefix has already been glued on, so `/admin` + `users` arrives as the perfectly
 * well-formed `/adminusers`. Only here is the route's own pattern still visible.
 */
final class IoRouteCollectorProxy extends RouteCollectorProxy
{
    /**
     * @param string[] $methods
     * @param callable|string $callable
     */
    public function map(array $methods, string $pattern, $callable): RouteInterface
    {
        $this->assertPattern($pattern);

        return parent::map($methods, $pattern, $callable);
    }

    /**
     * @param callable|string $callable
     */
    public function group(string $pattern, $callable): RouteGroupInterface
    {
        $this->assertPattern($pattern);

        return parent::group($pattern, $callable);
    }

    /**
     * An empty pattern is allowed: it is how a route is declared at the group's own path.
     */
    private function assertPattern(string $pattern): void
    {
        if ($pattern !== '' && !str_starts_with($pattern, '/')) {
            throw RoutePatternException::for($pattern, $this->groupPattern);
        }
    }
}
