<?php

declare(strict_types=1);

namespace apexl\Io\modules\user\services;

use Psr\Http\Message\ServerRequestInterface;

/**
 * Tells "you sent us a credential and it did not authenticate" apart from
 * "you sent us no credential at all". Pure — no container, no DB — so it is
 * unit-testable on its own.
 */
final class RejectedCredential
{
    /** Wire value for the 401 body / WWW-Authenticate hint. */
    public const string ERROR_INVALID_TOKEN = 'invalid_token';

    /**
     * True when a bearer credential was presented and SessionMiddleware could
     * not authenticate it — expired, bad signature, or a session that is gone.
     * SessionMiddleware swallows all three and hands an anonymous user down the
     * stack, so the Authorization header plus the `authenticated` attribute is
     * the only evidence left that the caller ever tried.
     */
    public static function wasPresented(ServerRequestInterface $request): bool
    {
        if ($request->getAttribute('authenticated') === true) {
            return false;
        }

        return self::isBearer($request->getHeaderLine('Authorization'));
    }

    /** A non-empty Bearer credential — an empty or malformed header is "none offered". */
    public static function isBearer(string $authorizationHeader): bool
    {
        return preg_match('/^Bearer\s+\S/', $authorizationHeader) === 1;
    }
}
