<?php

declare(strict_types=1);

namespace Apexl\Io\Exceptions;

use Exception;
use InvalidArgumentException;

/**
 * A URL was asked for without a value the route requires.
 *
 * Thrown rather than silently dropping the segment: a pattern with a hole cut out of it is
 * still a valid-looking URL, and it points somewhere else.
 */
final class MissingRouteValueException extends Exception
{
    public static function for(string $route, string $placeholder): self
    {
        return new self(sprintf(
            'Route "%s" needs a value for {%s}.',
            $route,
            $placeholder,
        ));
    }

    /**
     * Slim raises a bare InvalidArgumentException naming the segment it could not fill —
     * "Missing data for URL segment: id". The name is worth keeping and the type is not.
     */
    public static function from(string $route, InvalidArgumentException $exception): self
    {
        $placeholder = preg_match('/segment:\s*(\S+)/', $exception->getMessage(), $matches)
            ? $matches[1]
            : null;

        return new self(
            $placeholder !== null
                ? sprintf('Route "%s" needs a value for {%s}.', $route, $placeholder)
                : sprintf('Route "%s": %s', $route, $exception->getMessage()),
            previous: $exception,
        );
    }
}
