/**
 * Read the ShortcutXL session file written by the XLL's HTTP server.
 *
 * The XLL generates a random bearer token on startup and writes it
 * (along with the port) to %APPDATA%\ShortcutXL\session.json.
 * The agent reads this file to authenticate requests to the XLL.
 *
 * Important boundary: this is one global session file, not a per-process or
 * per-workbook registry. The runtime assumes one Excel/XLL process owns the
 * published session at a time. If multiple Excel processes load the XLL
 * concurrently, last-writer-wins session publication can point the runtime at
 * the wrong port/token pair.
 *
 * Format: { "port": 8080, "token": "hex..." }
 */
import { readFileSync } from 'fs';
import { join } from 'path';
import { requireLocalExcelHttpRequestUrl } from './http-url.js';
let cachedSession = null;
function getSessionFilePath() {
    const appData = process.env.APPDATA;
    if (!appData) {
        throw new Error('APPDATA environment variable not set');
    }
    return join(appData, 'ShortcutXL', 'session.json');
}
export function readXllSessionFromDisk() {
    try {
        const raw = readFileSync(getSessionFilePath(), 'utf-8');
        const data = JSON.parse(raw);
        if (typeof data.port === 'number' && typeof data.token === 'string' && data.token.length > 0) {
            return {
                port: data.port,
                token: data.token,
                ...(typeof data.error === 'string' && data.error.length > 0 ? { error: data.error } : {})
            };
        }
    }
    catch {
        // File doesn't exist or is malformed — XLL may not be running
    }
    return null;
}
/**
 * Read the XLL session file. Returns { port, token } or null if unavailable.
 * Caches the result — the token is stable for the lifetime of the Excel process.
 * This cache is only safe while a single Excel/XLL process owns session.json.
 */
function readXllSession() {
    if (cachedSession)
        return cachedSession;
    cachedSession = readXllSessionFromDisk();
    return cachedSession;
}
/**
 * Clear the cached session so the next readXllSession() re-reads from disk.
 * Useful after Excel restarts.
 */
export function clearXllSessionCache() {
    cachedSession = null;
}
/**
 * Check if the XLL reported an initialization error in session.json.
 * Returns the error string, or undefined if no error.
 */
export function readXllSessionError() {
    const session = readXllSession();
    return session?.error;
}
/**
 * Get the Authorization header value for XLL requests, or undefined
 * if no session file is available (falls back to unauthenticated).
 */
function getXllAuthHeader() {
    const session = readXllSession();
    return session ? `Bearer ${session.token}` : undefined;
}
/**
 * Authenticated fetch to the XLL HTTP server.
 *
 * Injects the bearer token from the session file and retries once on 403
 * (handles stale cached token after Excel restart).
 */
export async function xllFetch(url, init) {
    const safeUrl = requireLocalExcelHttpRequestUrl(url);
    const headers = new Headers(init?.headers);
    const auth = getXllAuthHeader();
    if (auth)
        headers.set('Authorization', auth);
    let response = await fetch(safeUrl, { ...init, headers: new Headers(headers) });
    if (response.status === 403) {
        clearXllSessionCache();
        const freshAuth = getXllAuthHeader();
        if (freshAuth)
            headers.set('Authorization', freshAuth);
        response = await fetch(safeUrl, { ...init, headers: new Headers(headers) });
    }
    return response;
}
//# sourceMappingURL=session.js.map