import { Colors } from '@neodx/colors';
import { IncomingMessage, OutgoingMessage } from 'http';
import { b as Logger } from '../_internal/types-BxgckgWg.js';

declare const HTTP_LOG_START_TIME_SYMBOL: unique symbol;

interface HttpLoggerParams<
  Req extends IncomingMessage = IncomingMessage,
  Res extends OutgoingMessage = OutgoingMessage
> {
  /**
   * Custom logger instance.
   * @default createLogger()
   */
  logger?: Logger<HttpLogLevels>;
  /**
   * Custom colors instance
   * @see `@neodx/colors`
   */
  colors?: Colors;
  /**
   * If `true`, the logger will only log the pre-formatted message without any additional metadata.
   * @default process.env.NODE_ENV === 'development'
   */
  simple?: boolean;
  /**
   * Optional function to extract/create request ID.
   * @default built-in simple safe number counter
   */
  getRequestId?: (req: Req, res: Res) => string | number;
  /**
   * Extract shared metadata for every produced log
   */
  getMeta?: (req: Req, res: Res) => Record<string, unknown>;
  /**
   * Extract metadata for request logs
   */
  getRequestMeta?: (ctx: HttpResponseContext<Req, Res>) => Record<string, unknown>;
  /**
   * Custom incoming request message formatter
   */
  getRequestMessage?: (ctx: HttpResponseContext<Req, Res>) => string;
  /**
   * Extract metadata for success response logs
   */
  getResponseMeta?: (ctx: HttpResponseContext<Req, Res>) => Record<string, unknown>;
  /**
   * Custom success response message formatter
   */
  getResponseMessage?: (ctx: HttpResponseContext<Req, Res>) => string;
  /**
   * Extract metadata for error response logs
   */
  getErrorMeta?: (ctx: HttpResponseContext<Req, Res>) => Record<string, unknown>;
  /**
   * Custom error response message formatter
   */
  getErrorMessage?: (ctx: HttpResponseContext<Req, Res>) => string;
  /**
   * Whether to log anything at all.
   * @default true
   */
  shouldLog?: boolean | ((req: Req, res: Res) => boolean);
  /**
   * Prevents logging of errors.
   * @default true
   */
  shouldLogError?: boolean | ((ctx: HttpResponseContext<Req, Res>) => boolean);
  /**
   * Prevents built-in logging of requests.
   * DISABLED BY DEFAULT, because it can be very verbose.
   * @default false
   */
  shouldLogRequest?: boolean | ((ctx: HttpResponseContext<Req, Res>) => boolean);
  /**
   * Prevents built-in logging of responses.
   * @default true
   */
  shouldLogResponse?: boolean | ((ctx: HttpResponseContext<Req, Res>) => boolean);
}
interface HttpLoggerMetaKeys {
  req: string;
  res: string;
  err: string;
  requestId: string;
  responseTime: string;
}
interface HttpResponseContext<
  Req extends IncomingMessage = IncomingMessage,
  Res extends OutgoingMessage = OutgoingMessage
> {
  req: Req;
  res: Res;
  error?: Error;
  logger: Logger<HttpLogLevels>;
  colors: Colors;
  responseTime: number;
}
type HttpRequestId = string | number;
type HttpLogLevels = 'debug' | 'error' | 'info' | 'done';
declare module 'http' {
  interface IncomingMessage {
    id: HttpRequestId;
    log: Logger<HttpLogLevels>;
  }
  interface ServerResponse {
    err?: Error | undefined;
  }
  interface OutgoingMessage {
    [HTTP_LOG_START_TIME_SYMBOL]: number;
  }
}
declare function createHttpLogger<
  Req extends IncomingMessage = IncomingMessage,
  Res extends OutgoingMessage = OutgoingMessage
>({
  simple,
  colors,
  logger: rootLogger,
  getRequestId,
  getMeta,
  getErrorMeta,
  getErrorMessage,
  getRequestMeta,
  getRequestMessage,
  getResponseMeta,
  getResponseMessage,
  shouldLog,
  shouldLogError,
  shouldLogRequest,
  shouldLogResponse
}?: HttpLoggerParams<Req, Res>): (req: Req, res: Res, next?: () => void) => void;

export {
  type HttpLogLevels,
  type HttpLoggerMetaKeys,
  type HttpLoggerParams,
  type HttpRequestId,
  type HttpResponseContext,
  createHttpLogger
};
