/**
 * Logger - Redacted user-facing logging
 * DD §16.2. Uses SecretRedactor.
 *
 * @module packages/runtime/src/logging/Logger
 */

import { appendFileSync, mkdirSync, existsSync } from 'fs'
import { join } from 'path'
import { get_shared_redactor } from '../security/SecretRedactor.js'

export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'fatal'

export class Logger {
  private log_dir: string
  private redactor = get_shared_redactor()
  private level: LogLevel

  constructor(log_dir: string, level: LogLevel = 'info') {
    this.log_dir = log_dir
    this.level = level
    if (!existsSync(log_dir)) mkdirSync(log_dir, { recursive: true })
  }

  log(level: LogLevel, message: string, context?: Record<string, unknown>): void {
    if (!this.should_log(level)) return

    const entry = {
      timestamp: new Date().toISOString(),
      level,
      message: this.redactor.redact(message).redacted,
      context: context ? this.redactor.redact(JSON.stringify(context)).redacted : undefined
    }

    const line = JSON.stringify(entry) + '\n'
    appendFileSync(this.air_log_path(), line, 'utf-8')
  }

  debug(msg: string, ctx?: Record<string, unknown>) { this.log('debug', msg, ctx) }
  info(msg: string, ctx?: Record<string, unknown>) { this.log('info', msg, ctx) }
  warn(msg: string, ctx?: Record<string, unknown>) { this.log('warn', msg, ctx) }
  error(msg: string, ctx?: Record<string, unknown>) { this.log('error', msg, ctx) }
  fatal(msg: string, ctx?: Record<string, unknown>) { this.log('fatal', msg, ctx) }

  air_log_path(): string { return join(this.log_dir, 'air.log') }
  developer_log_path(): string { return join(this.log_dir, 'air.developer.log') }

  private should_log(level: LogLevel): boolean {
    const levels: LogLevel[] = ['debug', 'info', 'warn', 'error', 'fatal']
    return levels.indexOf(level) >= levels.indexOf(this.level)
  }
}
