import { readFile, writeFile, unlink } from "node:fs/promises";
import { platform } from "node:os";
import { getAuthPath } from "../utils/paths.js";
const REQUIRED_FIELDS = [
    "machine_key",
    "access_token",
    "refresh_token",
    "expires_at",
    "user_id",
];
/**
 * Validates that a parsed object has the correct AuthTokens shape.
 */
function isValidTokens(data) {
    if (typeof data !== "object" || data === null)
        return false;
    const obj = data;
    return (typeof obj.machine_key === "string" &&
        typeof obj.access_token === "string" &&
        typeof obj.refresh_token === "string" &&
        typeof obj.expires_at === "number" &&
        typeof obj.user_id === "string" &&
        REQUIRED_FIELDS.every((f) => f in obj));
}
/**
 * Save auth tokens to auth.json with 0600 permissions (Unix).
 */
export async function saveTokens(tokens) {
    const mode = platform() === "win32" ? undefined : 0o600;
    const json = JSON.stringify(tokens, null, 2) + "\n";
    await writeFile(getAuthPath(), json, { mode });
}
/**
 * Load auth tokens from auth.json.
 * Returns null if the file doesn't exist or has invalid structure.
 */
export async function loadTokens() {
    try {
        const content = await readFile(getAuthPath(), "utf-8");
        const data = JSON.parse(content);
        if (!isValidTokens(data))
            return null;
        return data;
    }
    catch {
        return null;
    }
}
/**
 * Remove auth.json (clear tokens).
 */
export async function clearTokens() {
    try {
        await unlink(getAuthPath());
    }
    catch {
        // Ignore if file doesn't exist
    }
}
/**
 * Check if valid, non-expired tokens exist.
 * Returns true if tokens are present and expires_at is in the future.
 */
export async function hasValidTokens() {
    const tokens = await loadTokens();
    if (!tokens)
        return false;
    const now = Math.floor(Date.now() / 1000);
    return tokens.expires_at > now;
}
//# sourceMappingURL=token-storage.js.map