import { AsyncLocalStorage } from "node:async_hooks";
import { INTERNAL_RANGO_DEBUG } from "../internal-debug.js";
const routerLogContext = new AsyncLocalStorage();
const requestIds = new WeakMap();
let requestCounter = 0;
let transactionCounter = 0;
function nextId(prefix, counter) {
    return `${prefix}${counter.toString(36)}`;
}
function getHeaderRequestId(request) {
    const candidate = request.headers.get("x-rsc-router-request-id") ??
        request.headers.get("x-request-id") ??
        request.headers.get("cf-ray");
    if (!candidate)
        return null;
    const trimmed = candidate.trim();
    return trimmed.length > 0 ? trimmed : null;
}
function getOrCreateRequestId(request) {
    const existing = requestIds.get(request);
    if (existing)
        return existing;
    const fromHeaders = getHeaderRequestId(request);
    if (fromHeaders) {
        requestIds.set(request, fromHeaders);
        return fromHeaders;
    }
    requestCounter += 1;
    const generated = nextId("req-", requestCounter);
    requestIds.set(request, generated);
    return generated;
}
export function runWithRouterLogContext(options, fn) {
    if (!INTERNAL_RANGO_DEBUG) {
        return fn();
    }
    const requestId = getOrCreateRequestId(options.request);
    transactionCounter += 1;
    const transactionId = `${options.transaction}-${nextId("tx-", transactionCounter)}`;
    return routerLogContext.run({
        requestId,
        transactionId,
        depth: 0,
    }, fn);
}
export function withRouterLogScope(label, fn) {
    const ctx = routerLogContext.getStore();
    if (!INTERNAL_RANGO_DEBUG || !ctx) {
        return fn();
    }
    debugLog(label, "start");
    return routerLogContext.run({ ...ctx, depth: ctx.depth + 1 }, () => {
        try {
            const result = fn();
            if (result && typeof result.then === "function") {
                return result.finally(() => {
                    debugLog(label, "end");
                });
            }
            debugLog(label, "end");
            return result;
        }
        catch (error) {
            debugLog(label, "error", { error: String(error) });
            throw error;
        }
    });
}
export function isRouterDebugEnabled() {
    return INTERNAL_RANGO_DEBUG && !!routerLogContext.getStore();
}
function formatPrefix(scope) {
    const ctx = routerLogContext.getStore();
    if (!ctx)
        return `[Router][${scope}]`;
    const indent = "  ".repeat(ctx.depth);
    return `[Router][req:${ctx.requestId}][tx:${ctx.transactionId}] ${indent}[${scope}]`;
}
export function debugLog(scope, message, details) {
    if (!isRouterDebugEnabled())
        return;
    const prefix = formatPrefix(scope);
    if (details) {
        console.log(`${prefix} ${message}`, details);
        return;
    }
    console.log(`${prefix} ${message}`);
}
export function debugWarn(scope, message, details) {
    if (!isRouterDebugEnabled())
        return;
    const prefix = formatPrefix(scope);
    if (details) {
        console.warn(`${prefix} ${message}`, details);
        return;
    }
    console.warn(`${prefix} ${message}`);
}
//# sourceMappingURL=logging.js.map