<?php

declare(strict_types=1);

namespace App\Tests\Unit\Auth;

use App\Domain\Auth\Token;
use App\Domain\Auth\TokenKind;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;

final class TokenTest extends TestCase
{
    #[DataProvider('validTokens')]
    public function testParsesValidTokens(string $raw, TokenKind $expectedKind): void
    {
        $token = Token::parse($raw);
        self::assertNotNull($token);
        self::assertSame($expectedKind, $token->kind);
        self::assertSame(substr($raw, 0, 8), $token->prefix());
    }

    /**
     * @return iterable<string, array{string, TokenKind}>
     */
    public static function validTokens(): iterable
    {
        // 32 chars from base32 alphabet
        $body = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
        yield 'reporter' => ['irdb_rep_' . $body, TokenKind::Reporter];
        yield 'consumer' => ['irdb_con_' . $body, TokenKind::Consumer];
        yield 'admin' => ['irdb_adm_' . $body, TokenKind::Admin];
        yield 'service' => ['irdb_svc_' . $body, TokenKind::Service];
    }

    #[DataProvider('invalidTokens')]
    public function testRejectsInvalidTokens(string $raw): void
    {
        self::assertNull(Token::parse($raw));
    }

    /**
     * @return iterable<string, array{string}>
     */
    public static function invalidTokens(): iterable
    {
        yield 'empty' => [''];
        yield 'no prefix' => ['foo_bar_baz'];
        yield 'wrong tag' => ['irdb_xyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'];
        yield 'too short body' => ['irdb_adm_ABCDEFGH'];
        yield 'lowercase body' => ['irdb_adm_abcdefghijklmnopqrstuvwxyz234567'];
        yield 'invalid base32 char' => ['irdb_adm_ABCDEFGHIJKLMNOPQRSTUVWXYZ234560'];
        yield 'too long body' => ['irdb_adm_ABCDEFGHIJKLMNOPQRSTUVWXYZ234567ABCD'];
        yield 'missing underscore' => ['irdbadmABCDEFGHIJKLMNOPQRSTUVWXYZ234567'];
    }
}
