import path from "node:path";
import fs from "node:fs";
import { Writable } from "node:stream";
import pino from "pino";
import { pinoHttp } from "pino-http";
import pretty from "pino-pretty";
import { readConfigFile } from "../config-file.js";
import { resolveDefaultLogsDir, resolveHomeAwarePath } from "../home-paths.js";
function resolveServerLogDir() {
    const envOverride = process.env.RUDDER_LOG_DIR?.trim();
    if (envOverride)
        return resolveHomeAwarePath(envOverride);
    const fileLogDir = readConfigFile()?.logging.logDir?.trim();
    if (fileLogDir)
        return resolveHomeAwarePath(fileLogDir);
    return resolveDefaultLogsDir();
}
const logDir = resolveServerLogDir();
fs.mkdirSync(logDir, { recursive: true });
function formatLocalDateKey(date) {
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, "0");
    const day = String(date.getDate()).padStart(2, "0");
    return `${year}-${month}-${day}`;
}
function resolveDailyLogFilePath(baseDir, date) {
    return path.join(baseDir, `server-${formatLocalDateKey(date)}.log`);
}
class DailyFileStream extends Writable {
    baseDir;
    currentDateKey = null;
    currentStream = null;
    constructor(baseDir) {
        super();
        this.baseDir = baseDir;
    }
    ensureStream(date) {
        const dateKey = formatLocalDateKey(date);
        if (this.currentStream && this.currentDateKey === dateKey) {
            return this.currentStream;
        }
        if (this.currentStream) {
            this.currentStream.end();
            this.currentStream = null;
        }
        fs.mkdirSync(this.baseDir, { recursive: true });
        const nextStream = fs.createWriteStream(resolveDailyLogFilePath(this.baseDir, date), { flags: "a" });
        this.currentDateKey = dateKey;
        this.currentStream = nextStream;
        return nextStream;
    }
    _write(chunk, encoding, callback) {
        const stream = this.ensureStream(new Date());
        stream.write(chunk, encoding, callback);
    }
    _final(callback) {
        if (!this.currentStream) {
            callback();
            return;
        }
        this.currentStream.end(() => callback());
    }
}
const sharedOpts = {
    translateTime: "HH:MM:ss",
    ignore: "pid,hostname",
    singleLine: true,
};
const consolePrettyStream = pretty({
    ...sharedOpts,
    ignore: "pid,hostname,req,res,responseTime",
    colorize: true,
    destination: 1,
});
const filePrettyStream = pretty({
    ...sharedOpts,
    colorize: false,
    destination: new DailyFileStream(logDir),
});
export const logger = pino({
    level: "debug",
}, pino.multistream([
    { stream: consolePrettyStream, level: "info" },
    { stream: filePrettyStream, level: "debug" },
]));
export const httpLogger = pinoHttp({
    logger,
    customLogLevel(_req, res, err) {
        if (err || res.statusCode >= 500)
            return "error";
        if (res.statusCode >= 400)
            return "warn";
        return "info";
    },
    customSuccessMessage(req, res) {
        return `${req.method} ${req.url} ${res.statusCode}`;
    },
    customErrorMessage(req, res, err) {
        const ctx = res.__errorContext;
        const errMsg = ctx?.error?.message || err?.message || res.err?.message || "unknown error";
        return `${req.method} ${req.url} ${res.statusCode} — ${errMsg}`;
    },
    customProps(req, res) {
        if (res.statusCode >= 400) {
            const ctx = res.__errorContext;
            if (ctx) {
                return {
                    errorContext: ctx.error,
                    reqBody: ctx.reqBody,
                    reqParams: ctx.reqParams,
                    reqQuery: ctx.reqQuery,
                };
            }
            const props = {};
            const { body, params, query } = req;
            if (body && typeof body === "object" && Object.keys(body).length > 0) {
                props.reqBody = body;
            }
            if (params && typeof params === "object" && Object.keys(params).length > 0) {
                props.reqParams = params;
            }
            if (query && typeof query === "object" && Object.keys(query).length > 0) {
                props.reqQuery = query;
            }
            if (req.route?.path) {
                props.routePath = req.route.path;
            }
            return props;
        }
        return {};
    },
});
//# sourceMappingURL=logger.js.map