const assert = require("assert");
const fs = require("fs");
const path = require("path");

const root = path.join(__dirname, "..");
const sandbox = fs.mkdtempSync(path.join(root, ".tmp-lumi-logging-"));
const serviceDir = path.join(sandbox, "src", "services");
fs.mkdirSync(serviceDir, { recursive: true });
for (const file of ["db.js", "logger.js", "web-events.js"]) {
  fs.copyFileSync(path.join(root, "src", "services", file), path.join(serviceDir, file));
}

let database;
try {
  database = require(path.join(serviceDir, "db.js"));
  database.db.exec(`CREATE TABLE logs (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    level TEXT NOT NULL,
    message TEXT NOT NULL,
    details TEXT,
    created_at INTEGER NOT NULL
  )`);
  database.migrate();
  const logger = require(path.join(serviceDir, "logger.js"));
  const { db } = database;
  const columns = db.prepare("PRAGMA table_info(logs)").all().map((column) => column.name);
  for (const column of ["source", "category", "event", "request_id"]) {
    assert(columns.includes(column), `logs.${column} migration`);
  }

  logger.log("info", "Legacy-compatible entry", { status: "ready" });
  const pluginLog = logger.createLogger("plugin:example", { category: "plugin" });
  pluginLog.warn("Example warning", {
    access_token: "must-not-be-stored",
    nested: { password: "also-secret", safe: "visible" },
    url: "https://example.com/run?token=hidden&mode=safe"
  }, { event: "example_warning", requestId: "request-123" });
  logger.withLogContext({ source: "core:test", category: "verification", event: "context_entry" }, () => {
    logger.log("debug", "Context-aware entry", "authorization=private-value");
  });

  const all = logger.listLogs({ limit: 20 });
  assert.equal(all.length, 3);
  const warning = all.find((entry) => entry.event === "example_warning");
  assert.equal(warning.source, "plugin:example");
  assert.equal(warning.category, "plugin");
  assert.equal(warning.request_id, "request-123");
  assert(warning.details.includes("[REDACTED]"));
  assert.equal(warning.details.includes("must-not-be-stored"), false);
  assert.equal(warning.details.includes("also-secret"), false);
  assert.equal(warning.details.includes("token=hidden"), false);
  assert(warning.details.includes("visible"));

  assert.equal(logger.listLogs({ sources: ["plugin:example"] }).length, 1);
  assert.equal(logger.listLogs({ categories: ["verification"] }).length, 1);
  assert.equal(logger.listLogs({ search: "request-123" }).length, 1);
  assert.equal(logger.listLogs({ levels: ["error"] }).length, 0);
  const summary = logger.summarizeLogs({});
  assert.equal(summary.total, 3);
  assert.equal(summary.levels.warn, 1);
  assert(logger.listLogFacets().sources.some((item) => item.value === "plugin:example" && item.count === 1));

  db.prepare("UPDATE logs SET created_at = ? WHERE message = ?").run(
    Date.now() - 45 * 24 * 60 * 60 * 1000,
    "Legacy-compatible entry"
  );
  const cleanup = logger.cleanupLogs({ maxAgeDays: 30, maxEntries: 1000 });
  assert.equal(cleanup.expired, 1);
  assert.equal(logger.listLogs({ search: "Legacy-compatible" }).length, 0);

  const logView = fs.readFileSync(path.join(root, "src", "web", "views", "admin-logs.ejs"), "utf8");
  assert.match(logView, /data-log-source/);
  assert.match(logView, /data-log-category/);
  assert.match(logView, /data-log-live-status/);
  assert.match(logView, /name="format"/);
  const serverSource = fs.readFileSync(path.join(root, "src", "web", "server.js"), "utf8");
  assert.match(serverSource, /app\.post\("\/admin\/logs\/retention"/);
  assert.match(serverSource, /summarizeLogs\(query\)/);
  assert.match(serverSource, /"admin_action"/);

  console.log("Logging verification passed: structured scope, redaction, search, summaries, retention, admin audit, and live UI wiring.");
} finally {
  try { database?.db?.close(); } catch {}
  fs.rmSync(sandbox, { recursive: true, force: true });
}
