<?php

use FastRoute\RouteCollector;
use Laminas\Diactoros\ResponseFactory;
use Laminas\Diactoros\ServerRequestFactory;
use Laminas\HttpHandlerRunner\Emitter\SapiEmitter;
use Laminas\HttpHandlerRunner\RequestHandlerRunner;
use Laminas\Stratigility\Middleware\ErrorHandler;
use Laminas\Stratigility\MiddlewarePipe;
use Mezzio\Router\FastRouteRouter;
use Mezzio\Router\Middleware\DispatchMiddleware;
use Mezzio\Router\Middleware\RouteMiddleware;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;

require './vendor/autoload.php';

$responseFactory = new ResponseFactory();
$router          = new FastRouteRouter();
$routes          = new RouteCollector($router);
$app             = new MiddlewarePipe();

$app->pipe(new ErrorHandler([$responseFactory, 'createResponse']));
$app->pipe(new RouteMiddleware($router));
$app->pipe(new DispatchMiddleware());

$routes->get('/hello', new class ($responseFactory) implements RequestHandlerInterface {
    /** @var ResponseFactoryInterface */
    private $responseFactory;

    public function __construct(ResponseFactoryInterface $responseFactory)
    {
        $this->responseFactory = $responseFactory;
    }

    public function handle(ServerRequestInterface $request): ResponseInterface
    {
        $response = $this->responseFactory->createResponse();
        $response->getBody()->write('Hello world');
        return $response;
    }
});

$runner = new RequestHandlerRunner(
    $app,
    new SapiEmitter(),
    [ServerRequestFactory::class, 'fromGlobals'],
    function (Throwable $error) use ($responseFactory): ResponseInterface {
        $response = $responseFactory->createResponse(500)
            ->withHeader('Content-Type', 'application/json');
        $response->getBody()->write(json_encode([
            'error' => $error->getMessage(),
            'trace' => $error->getTrace(),
        ]));
        return $response;
    }
);
$runner->run();