<?php

declare(strict_types=1);

namespace Ekdos\Http\Middleware;

use Ekdos\Auth\Session;
use Ekdos\Auth\SessionCookie;
use Ekdos\Auth\SessionStore;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface as Handler;

/**
 * Loest das Cookie in eine Sitzung auf und haengt sie an die Anfrage.
 * Sie weist nichts ab: das uebernehmen RequireAuth und RequirePermission.
 */
final readonly class SessionMiddleware implements MiddlewareInterface
{
    public const string ATTRIBUTE = 'session';

    public function __construct(
        private SessionStore $sessions,
        private SessionCookie $cookie,
    ) {}

    public function process(Request $request, Handler $handler): Response
    {
        $id = $this->cookie->read($request);
        $session = $id === '' ? null : $this->sessions->read($id);

        if ($session !== null) {
            $this->sessions->touch($session);
        }

        return $handler->handle($request->withAttribute(self::ATTRIBUTE, $session));
    }

    public static function of(Request $request): ?Session
    {
        $session = $request->getAttribute(self::ATTRIBUTE);

        return $session instanceof Session ? $session : null;
    }
}
