<?php

use PHPUnit\Framework\TestCase;

class SessionsTest extends TestCase {
	private function create_sessions_table(): void {
		app() -> thin_builder -> query("CREATE TABLE sessions (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			uid INTEGER,
			status INTEGER DEFAULT 1,
			token VARCHAR(255),
			last_using_at DATETIME,
			update_at DATETIME,
			create_at DATETIME
		)");
	}

	private function drop_sessions_table(): void {
		app() -> thin_builder -> query("DROP TABLE IF EXISTS sessions");
	}

	protected function setUp(): void {
		$this -> create_sessions_table();
	}

	protected function tearDown(): void {
		$this -> drop_sessions_table();
	}

	public function test_create_returns_token_and_persists(): void {
		$sessions = new \SHServ\Sessions();
		$token = $sessions -> create(42);

		$this -> assertNotFalse($token);
		$this -> assertSame(64, strlen($token));

		$rows = app() -> thin_builder -> select('sessions', ['uid', 'token', 'status'], [['token', '=', $token]]);
		$this -> assertCount(1, $rows);
		$this -> assertEquals(42, (int) $rows[0]['uid']);
		$this -> assertEquals(1, (int) $rows[0]['status']);
	}

	public function test_get_session_by_token_returns_entity(): void {
		$sessions = new \SHServ\Sessions();
		$token = $sessions -> create(99);

		$session = $sessions -> get_session_by_token($token);
		$this -> assertInstanceOf(\SHServ\Entities\Session::class, $session);
		$this -> assertEquals(99, (int) $session -> get('uid'));
		$this -> assertSame($token, $session -> get('token'));
	}

	public function test_get_session_by_invalid_token_returns_null(): void {
		$sessions = new \SHServ\Sessions();
		$this -> assertNull($sessions -> get_session_by_token('nonexistent-token'));
	}

	public function test_close_updates_status(): void {
		$sessions = new \SHServ\Sessions();
		$token = $sessions -> create(7);

		$result = $sessions -> close($token);
		$this -> assertTrue($result);

		$session = $sessions -> get_session_by_token($token);
		$this -> assertNull($session);

		$rows = app() -> thin_builder -> select('sessions', ['status'], [['token', '=', $token]]);
		$this -> assertEquals(2, (int) $rows[0]['status']);
	}
}
