/**
 * Structured logger for Actuate CMS (audit issue L7).
 *
 * Why a dedicated module instead of `console.*`:
 *
 *   1. **Filterable in production.** Operators can set
 *      `ACTUATE_LOG_LEVEL=warn` to silence routine info logs without losing
 *      error visibility — `console.*` calls can't be silenced without
 *      monkey-patching.
 *
 *   2. **Structured output for log aggregators.** Setting
 *      `ACTUATE_LOG_FORMAT=json` switches to one-line JSON entries with
 *      consistent fields (`ts`, `level`, `scope`, `msg`, `details`),
 *      ready for ingestion by Datadog, Sentry, or CloudWatch.
 *
 *   3. **Scoped namespaces.** `createLogger('rate-limit')` prefixes every
 *      message with `[actuate][rate-limit]` so a grep finds related
 *      entries instantly.
 *
 * **Migration path:** existing `console.*` calls keep working. New code and
 * security-sensitive paths use the logger. Replace `console.*` callsites
 * incrementally as files are touched.
 */
const LEVEL_RANK = {
    silent: 0,
    error: 10,
    warn: 20,
    info: 30,
    debug: 40,
};
function resolveLevel() {
    const raw = (process.env.ACTUATE_LOG_LEVEL ?? '').toLowerCase();
    if (raw === 'silent' || raw === 'error' || raw === 'warn' || raw === 'info' || raw === 'debug') {
        return raw;
    }
    // Default: warn in production, info elsewhere. Tests run with NODE_ENV=test
    // and benefit from `info` so failing assertions show context.
    return process.env.NODE_ENV === 'production' ? 'warn' : 'info';
}
function isJsonFormat() {
    return (process.env.ACTUATE_LOG_FORMAT ?? '').toLowerCase() === 'json';
}
function shouldLog(level) {
    const current = resolveLevel();
    return LEVEL_RANK[level] <= LEVEL_RANK[current];
}
function emit(level, scope, msg, details) {
    if (!shouldLog(level))
        return;
    const sink = level === 'error'
        ? console.error
        : level === 'warn'
            ? console.warn
            : level === 'info'
                ? console.info
                : console.debug;
    if (isJsonFormat()) {
        sink(JSON.stringify({
            ts: new Date().toISOString(),
            level,
            scope,
            msg,
            ...(details ? { details } : {}),
        }));
        return;
    }
    const prefix = `[actuate][${scope}]`;
    if (details) {
        sink(prefix, msg, details);
    }
    else {
        sink(prefix, msg);
    }
}
/**
 * Create a logger scoped to a subsystem name (e.g. `rate-limit`, `oauth`).
 * Output format:
 *   text: `[actuate][rate-limit] Upstash failed { reason: '...' }`
 *   json: `{"ts":"...","level":"error","scope":"rate-limit","msg":"...","details":{...}}`
 */
export function createLogger(scope) {
    return {
        error: (msg, details) => emit('error', scope, msg, details),
        warn: (msg, details) => emit('warn', scope, msg, details),
        info: (msg, details) => emit('info', scope, msg, details),
        debug: (msg, details) => emit('debug', scope, msg, details),
    };
}
//# sourceMappingURL=logger.js.map