// lib/log.ts
// Copyright (C) 2025 DTP Technologies, LLC
// All Rights Reserved

import env from "../config/env.js";

import * as util from "node:util";

import dayjs from "dayjs";
import color from "ansicolor";

export enum TripwireLogLevel {
  debug = "debug",
  info = "info",
  warn = "warn",
  alert = "alert",
  error = "error",
  crit = "crit",
  fatal = "fatal",
}

export class TripwireLog {
  constructor() {}

  async debug(message: string, metadata?: unknown) {
    if (!env.log.levels.debug) {
      return;
    }
    return this.writeLog(TripwireLogLevel.debug, message, metadata);
  }

  async info(message: string, metadata?: unknown) {
    if (!env.log.levels.info) {
      return;
    }
    return this.writeLog(TripwireLogLevel.info, message, metadata);
  }

  async warn(message: string, metadata?: unknown) {
    if (!env.log.levels.warn) {
      return;
    }
    return this.writeLog(TripwireLogLevel.warn, message, metadata);
  }

  async alert(message: string, metadata?: unknown) {
    return this.writeLog(TripwireLogLevel.alert, message, metadata);
  }

  async error(message: string, metadata?: unknown) {
    return this.writeLog(TripwireLogLevel.error, message, metadata);
  }

  async crit(message: string, metadata?: unknown) {
    return this.writeLog(TripwireLogLevel.crit, message, metadata);
  }

  async fatal(message: string, metadata?: unknown) {
    return this.writeLog(TripwireLogLevel.fatal, message, metadata);
  }

  async writeLog(
    level: TripwireLogLevel,
    message: string,
    metadata?: unknown
  ): Promise<void> {
    const timestamp = new Date();
    let clevel = level.padEnd(5);
    switch (level) {
      case "debug":
        clevel = color.darkGray(clevel);
        break;
      case "info":
        clevel = color.green(clevel);
        break;
      case "warn":
        clevel = color.yellow(clevel);
        break;
      case "alert":
        clevel = color.red(clevel);
        break;
      case "error":
        clevel = color.bgRed.white(clevel);
        break;
      case "crit":
        clevel = color.bgRed.yellow(clevel);
        break;
      case "fatal":
        clevel = color.bgRed.darkGray(clevel);
        break;
    }

    const ccomponent = color.cyan("tripwire");
    const ctimestamp = color.darkGray(
      dayjs(timestamp).format("YYYY-MM-DD HH:mm:ss.SSS")
    );
    const cmessage = color.darkGray(message);

    if (metadata) {
      console.log(
        `${ctimestamp} ${clevel} ${ccomponent} ${cmessage}`,
        util.inspect(metadata, false, Infinity, true)
      );
    } else {
      console.log(`${ctimestamp} ${clevel} ${ccomponent} ${cmessage}`);
    }
  }
}

export default new TripwireLog();
