<?php

namespace MintyPHP\Tests\Service\Auth;

use MintyPHP\Http\SessionStore;
use MintyPHP\Service\Auth\MicrosoftOidcStateStoreService;
use PHPUnit\Framework\TestCase;

class MicrosoftOidcStateStoreServiceTest extends TestCase
{
    private array $previousSession = [];

    protected function setUp(): void
    {
        parent::setUp();
        $this->previousSession = $_SESSION ?? [];
        $_SESSION = [];
    }

    protected function tearDown(): void
    {
        $_SESSION = $this->previousSession;
        parent::tearDown();
    }

    public function testStoreAndConsumeIsSingleUse(): void
    {
        $store = new MicrosoftOidcStateStoreService(new SessionStore(), 600, 50);
        $store->store('state-a', ['tenant_id' => 5, 'nonce' => 'n1']);

        $first = $store->consume('state-a');
        $this->assertTrue($first['ok']);
        $this->assertSame(5, (int) (($first['entry']['tenant_id'] ?? 0)));

        $second = $store->consume('state-a');
        $this->assertFalse($second['ok']);
        $this->assertSame('state_invalid', (string) $second['error']);
    }

    public function testConsumeReturnsExpiredForOldState(): void
    {
        $store = new MicrosoftOidcStateStoreService(new SessionStore(), 1, 50);
        $store->store('state-old', [
            'tenant_id' => 9,
            'created_at' => time() - 120,
        ]);

        $result = $store->consume('state-old');
        $this->assertFalse($result['ok']);
        $this->assertSame('state_expired', (string) $result['error']);
    }

    public function testStoreRespectsMaxEntriesAndPrunesOldStates(): void
    {
        $store = new MicrosoftOidcStateStoreService(new SessionStore(), 600, 2);

        $store->store('state-1', ['created_at' => time() - 3]);
        $store->store('state-2', ['created_at' => time() - 2]);
        $store->store('state-3', ['created_at' => time() - 1]);

        $invalid = $store->consume('state-1');
        $this->assertFalse($invalid['ok']);
        $this->assertSame('state_invalid', (string) $invalid['error']);

        $valid2 = $store->consume('state-2');
        $this->assertTrue($valid2['ok']);

        $valid3 = $store->consume('state-3');
        $this->assertTrue($valid3['ok']);
    }
}
