<?php

declare(strict_types=1);

namespace app\vendor\apexl\io\src\Io\middleware;

use apexl\Io\modules\system\services\RequestResolver;
use DI\DependencyException;
use DI\NotFoundException;
use Invoker\CallableResolver;
use Invoker\Exception\NotCallableException;
use Invoker\Reflection\CallableReflection;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use ReflectionException;
use Slim\Routing\RouteContext;

final readonly class InjectIoRequest implements MiddlewareInterface
{
    public function __construct(private RequestResolver $requestResolver, private CallableResolver $callableResolver) {}

    /**
     * @throws ReflectionException
     * @throws DependencyException
     * @throws NotFoundException
     * @throws NotCallableException
     */
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        $route = $request->getAttribute(RouteContext::ROUTE);
        $callable = $route->getCallable();

        $callableReflection = CallableReflection::create($this->callableResolver->resolve($callable));
        $request = $this->requestResolver->resolve($callableReflection, $request);

        return $handler->handle($request);
    }
}
