<?php

declare(strict_types=1);

namespace Apexl\Tests\User\UnitTests;

use apexl\Io\modules\user\services\RejectedCredential;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
use Slim\Psr7\Factory\ServerRequestFactory;

/**
 * The 401-vs-403 discriminator. Pure — deliberately a plain TestCase
 * (no container, no DB).
 */
final class RejectedCredentialTest extends TestCase
{
    private function request(?string $authorization, mixed $authenticated = null): \Psr\Http\Message\ServerRequestInterface
    {
        $request = (new ServerRequestFactory())->createServerRequest('GET', '/anything');

        if ($authorization !== null) {
            $request = $request->withHeader('Authorization', $authorization);
        }

        return $authenticated === null
            ? $request
            : $request->withAttribute('authenticated', $authenticated);
    }

    // ── a credential was offered and did not authenticate → 401 territory ───

    #[Test]
    public function a_bearer_token_that_did_not_authenticate_counts_as_rejected(): void
    {
        self::assertTrue(RejectedCredential::wasPresented($this->request('Bearer expired.jwt.value')));
        self::assertTrue(RejectedCredential::wasPresented($this->request('Bearer garbage', false)));
    }

    // ── nothing was offered → the anonymous path, unchanged ─────────────────

    #[Test]
    public function no_authorization_header_is_not_a_rejected_credential(): void
    {
        self::assertFalse(RejectedCredential::wasPresented($this->request(null)));
    }

    #[Test]
    public function an_empty_or_malformed_bearer_is_not_a_rejected_credential(): void
    {
        self::assertFalse(RejectedCredential::wasPresented($this->request('')));
        self::assertFalse(RejectedCredential::wasPresented($this->request('Bearer')));
        self::assertFalse(RejectedCredential::wasPresented($this->request('Bearer   ')));
        self::assertFalse(RejectedCredential::wasPresented($this->request('Basic dXNlcjpwYXNz')));
    }

    // ── authenticated callers are never "rejected" — their denial is a 403 ──

    #[Test]
    public function an_authenticated_caller_is_never_a_rejected_credential(): void
    {
        self::assertFalse(RejectedCredential::wasPresented($this->request('Bearer good.jwt.value', true)));
    }

    #[Test]
    public function isBearer_accepts_only_a_non_empty_bearer_value(): void
    {
        self::assertTrue(RejectedCredential::isBearer('Bearer x'));
        self::assertTrue(RejectedCredential::isBearer("Bearer\tx"));
        self::assertFalse(RejectedCredential::isBearer('bearer x'));
        self::assertFalse(RejectedCredential::isBearer('x Bearer y'));
        self::assertFalse(RejectedCredential::isBearer(''));
    }
}
