import pino from 'pino';

import { getRequestContext } from '@/lib/request-context';

export const logger = pino({
  level: process.env.LOG_LEVEL ?? 'info',
  /**
   * Mix the active request context (request id, port id, user id) into
   * EVERY log line emitted within an API request - this is what makes
   * the super-admin error inspector usable: paste a request id into the
   * search and every log line that fired during that request comes back
   * keyed to it. Outside a request (queue jobs, scheduled tasks) the
   * mixin returns an empty object so the log line is unchanged.
   */
  mixin() {
    const ctx = getRequestContext();
    if (!ctx) return {};
    return {
      requestId: ctx.requestId,
      portId: ctx.portId || undefined,
      userId: ctx.userId || undefined,
    };
  },
  redact: {
    paths: [
      'password',
      'token',
      'secret',
      'accessKey',
      'secretKey',
      'creditCard',
      '*.password',
      '*.token',
      '*.secret',
      '*.accessKey',
      '*.secretKey',
      // Encrypted credential blobs surface in storage / smtp config logs
      // unintentionally; redact them defensively even though they're
      // already AES-encrypted at rest.
      '*.secretKeyEncrypted',
      '*.smtpPassEncrypted',
      '*.imapPassEncrypted',
      '*.proxyHmacSecretEncrypted',
      // HTTP authorization headers (Bearer tokens, Basic creds) leak via
      // err.config.headers on http-client error logs.
      '*.headers.authorization',
      '*.headers.Authorization',
      '*.headers["x-documenso-secret"]',
      '*.config.headers.Authorization',
      '*.config.headers.authorization',
      // Cookie headers can carry session tokens.
      '*.headers.cookie',
      '*.headers.Cookie',
      // Two-level nesting for things like `req.headers.authorization` or
      // `cfg.s3.secretKeyEncrypted`.
      '*.*.password',
      '*.*.token',
      '*.*.secret',
      '*.*.secretKeyEncrypted',
      '*.*.headers.authorization',
      '*.*.headers.Authorization',
    ],
    censor: '[REDACTED]',
  },
  transport:
    process.env.NODE_ENV !== 'production'
      ? { target: 'pino-pretty', options: { colorize: true } }
      : undefined,
  serializers: {
    err: pino.stdSerializers.err,
    req: pino.stdSerializers.req,
    res: pino.stdSerializers.res,
  },
});
