import { appendFileSync, existsSync, mkdirSync, renameSync, statSync } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
import { getConfig } from './config.mjs';

const __dirname = dirname(fileURLToPath(import.meta.url));
const LOG_DIR = join(__dirname, 'data');
const LOG_PATH = join(LOG_DIR, 'agent.log');
const LOG_ROTATED = join(LOG_DIR, 'agent.log.1');
const MAX_BYTES = 10 * 1024 * 1024; // 10MB

const LEVELS = { debug: 0, info: 1, warn: 2, error: 3 };

function ensureLogDir() {
  if (!existsSync(LOG_DIR)) {
    mkdirSync(LOG_DIR, { recursive: true });
  }
}

function rotateIfNeeded() {
  try {
    if (existsSync(LOG_PATH) && statSync(LOG_PATH).size > MAX_BYTES) {
      if (existsSync(LOG_ROTATED)) {
        // Remove old rotated file by overwriting — rename overwrites on most platforms
      }
      renameSync(LOG_PATH, LOG_ROTATED);
    }
  } catch {
    // Non-fatal — continue logging even if rotation fails
  }
}

function getMinLevel() {
  try {
    const cfg = getConfig();
    return LEVELS[cfg.logLevel] ?? LEVELS.info;
  } catch {
    return LEVELS.info;
  }
}

function writeEntry(level, module, message) {
  if (LEVELS[level] < getMinLevel()) return;

  const ts = new Date().toISOString();
  const line = `[${ts}] [${level.toUpperCase().padEnd(5)}] [${module}] ${message}\n`;

  // Console output
  if (level === 'error') {
    process.stderr.write(line);
  } else {
    process.stdout.write(line);
  }

  // File output
  try {
    ensureLogDir();
    rotateIfNeeded();
    appendFileSync(LOG_PATH, line, 'utf-8');
  } catch {
    // Non-fatal — don't crash the agent over logging failures
  }
}

/**
 * Create a logger for a named module.
 * @param {string} moduleName - Label shown in log entries, e.g. 'agent', 'server'
 * @returns {{ debug: Function, info: Function, warn: Function, error: Function }}
 */
export function createLogger(moduleName) {
  return {
    debug: (msg) => writeEntry('debug', moduleName, msg),
    info:  (msg) => writeEntry('info',  moduleName, msg),
    warn:  (msg) => writeEntry('warn',  moduleName, msg),
    error: (msg) => writeEntry('error', moduleName, msg),
  };
}
