<?php

declare(strict_types=1);

namespace ApiModel\Tests\Unit\Security;

use ApiModel\Infrastructure\Security\JwtSecretResolver;
use PHPUnit\Framework\TestCase;

final class JwtSecretResolverTest extends TestCase
{
    /** @var array<string, string|null> */
    private array $backup = [];

    protected function setUp(): void
    {
        parent::setUp();
        foreach (['JWT_SECRET', 'JWT_SECRET_PREVIOUS'] as $k) {
            $this->backup[$k] = $_ENV[$k] ?? null;
        }
    }

    protected function tearDown(): void
    {
        foreach ($this->backup as $k => $v) {
            if ($v === null) {
                unset($_ENV[$k], $_SERVER[$k]);
                putenv($k);
            } else {
                $_ENV[$k] = $v;
                $_SERVER[$k] = $v;
                putenv("{$k}={$v}");
            }
        }
        parent::tearDown();
    }

    private function put(string $key, string $value): void
    {
        $_ENV[$key] = $value;
        $_SERVER[$key] = $value;
        putenv("{$key}={$value}");
    }

    public function testSigningSecretThrowsWhenMissing(): void
    {
        $this->put('JWT_SECRET', '');

        $this->expectException(\RuntimeException::class);
        $this->expectExceptionMessage('JWT_SECRET no configurado');
        JwtSecretResolver::signingSecret();
    }

    public function testSigningSecretReturnsTrimmed(): void
    {
        $this->put('JWT_SECRET', '  my-secret  ');
        self::assertSame('my-secret', JwtSecretResolver::signingSecret());
    }

    public function testVerificationSecretsSingle(): void
    {
        $this->put('JWT_SECRET', 'primary');
        $this->put('JWT_SECRET_PREVIOUS', '');

        self::assertSame(['primary'], JwtSecretResolver::verificationSecrets());
    }

    public function testVerificationSecretsIncludesPreviousWhenDistinct(): void
    {
        $this->put('JWT_SECRET', 'new');
        $this->put('JWT_SECRET_PREVIOUS', 'old');

        self::assertSame(['new', 'old'], JwtSecretResolver::verificationSecrets());
    }

    public function testVerificationSecretsSkipsDuplicatePrevious(): void
    {
        $this->put('JWT_SECRET', 'same');
        $this->put('JWT_SECRET_PREVIOUS', 'same');

        self::assertSame(['same'], JwtSecretResolver::verificationSecrets());
    }
}
