// src/lib/log.ts
// Copyright (C) 2026 Robert Colbert <rob.colbert@openplatform.us>
// All Rights Reserved

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

import { DtpComponent } from "./component.ts";
import { DtpLogTransportConsole } from "./log-transport-console.js";
import { DtpLogTransportFile } from "./log-transport-file.js";
import { DtpLogTransport } from "./log-transport.js";
import { DtpLogFile } from "./log-file.js";

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

export class DtpLog {
  component: DtpComponent;
  transports: Array<DtpLogTransport> = [];

  constructor(component: DtpComponent, file?: DtpLogFile) {
    this.component = component;

    if (env.log.console.enabled) {
      this.transports.push(new DtpLogTransportConsole());
    }
    if (env.log.file.enabled && file) {
      this.transports.push(new DtpLogTransportFile(file));
    }
  }

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

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

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

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

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

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

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

  async writeLog(level: DtpLogLevel, message: string, metadata?: unknown) {
    const NOW = new Date();
    for (const transport of this.transports) {
      transport.writeLog(NOW, this.component, level, message, metadata);
    }
  }
}
