<?php

declare(strict_types=1);

namespace Tests\Integration;

use Tests\Support\DatabaseSeeder;
use Tests\Support\QdbTestCase;

final class SettingsApiTest extends QdbTestCase
{
    public function testAdminCanReadSettings(): void
    {
        $res = $this->api()->withToken($this->adminToken(), 'GET', 'settings');
        $this->assertApiOk($res);
        $this->assertArrayHasKey('settings', $res['data']);
        $this->assertArrayHasKey('activeSessions', $res['data']);
    }

    public function testSupervisorForbidden(): void
    {
        $token = $this->api()->loginWebAndGetToken(
            DatabaseSeeder::SUPERVISOR_USERNAME,
            DatabaseSeeder::PASSWORD
        )['token'];
        $res = $this->api()->withToken($token, 'GET', 'settings');
        $this->assertApiError($res, 'FORBIDDEN', 403);
    }

    public function testUpdateSettings(): void
    {
        $token = $this->adminToken();
        $res = $this->api()->withToken($token, 'PUT', 'settings', [
            'login_max_attempts'       => 8,
            'login_window_seconds'     => 1200,
            'login_lockout_seconds'    => 1200,
            'session_ttl_seconds'      => 86400,
            'temp_session_ttl_seconds' => 900,
        ]);
        $this->assertApiOk($res);
        $this->assertSame(8, $res['data']['settings']['login_max_attempts']);
    }

    public function testRevokeAllSessionsRequiresPhrase(): void
    {
        $res = $this->api()->withToken($this->adminToken(), 'POST', 'settings', [
            'action' => 'revokeAllSessions',
            'confirmPhrase' => 'wrong',
        ]);
        $this->assertApiError($res, 'CONFIRMATION_REQUIRED', 400);
    }

    public function testRevokeAllSessions(): void
    {
        $admin = $this->adminToken();
        $this->api()->loginWebAndGetToken(DatabaseSeeder::SUPERVISOR_USERNAME, DatabaseSeeder::PASSWORD);
        $res = $this->api()->withToken($admin, 'POST', 'settings', [
            'action'        => 'revokeAllSessions',
            'confirmPhrase' => 'REVOKE ALL SESSIONS',
        ]);
        $this->assertApiOk($res);
        $this->assertGreaterThanOrEqual(1, $res['data']['revokedSessions']);
        $check = $this->api()->withToken($admin, 'GET', 'session');
        $this->assertApiError($check, 'UNAUTHORIZED', 401);
    }
}
