// `session.ts` is the thin layer that loads or creates the device
// session at app startup. The keypair half is always materialised
// (loaded from the [KeyStore], or freshly generated when the slot is
// empty); the device-session-id half is read out of the [Cache] and
// is `null` until Phase 7's confirm-email-code handler stores it via
// [setDeviceSessionId]. A `null` deviceSessionId is the marker that
// the user must run the email-code login flow.
//
// Phase 7 wires the production caller (a layout-level loader that
// runs `loadDeviceSession` on first render and forwards the result
// into the Svelte session store). Phase 6 ships the persistence
// primitives this loader needs.

import type { Cache, DeviceKeypair, KeyStore } from "../platform/store/index";

export const SESSION_NAMESPACE = "session";
export const SESSION_ID_KEY = "device-session-id";

export interface DeviceSession {
	keypair: DeviceKeypair;
	deviceSessionId: string | null;
}

/**
 * loadDeviceSession returns the device session for the current
 * device. The keypair is loaded from `keyStore`; if the slot is
 * empty, a fresh non-exportable Ed25519 keypair is generated and
 * persisted. The returned `deviceSessionId` is `null` until Phase 7
 * registers the public key with the gateway and persists the
 * resulting id via [setDeviceSessionId].
 */
export async function loadDeviceSession(
	keyStore: KeyStore,
	cache: Cache,
): Promise<DeviceSession> {
	const existing = await keyStore.load();
	const keypair = existing ?? (await keyStore.generate());
	const stored = await cache.get<string>(SESSION_NAMESPACE, SESSION_ID_KEY);
	return { keypair, deviceSessionId: stored ?? null };
}

/**
 * setDeviceSessionId persists the device-session id returned by the
 * gateway's confirm-email-code response so subsequent app starts can
 * resume the session without re-login.
 */
export async function setDeviceSessionId(
	cache: Cache,
	deviceSessionId: string,
): Promise<void> {
	await cache.put(SESSION_NAMESPACE, SESSION_ID_KEY, deviceSessionId);
}

/**
 * clearDeviceSession wipes both the device keypair and the stored
 * device-session id. The next [loadDeviceSession] call will generate
 * a fresh keypair and report `deviceSessionId: null`, forcing
 * re-login. Used by user-driven logout and by gateway-driven
 * revocation paths.
 */
export async function clearDeviceSession(
	keyStore: KeyStore,
	cache: Cache,
): Promise<void> {
	await Promise.all([
		keyStore.clear(),
		cache.delete(SESSION_NAMESPACE, SESSION_ID_KEY),
	]);
}
