"use strict";

const assert = require("assert");
const fs = require("fs");
const os = require("os");
const path = require("path");
const { performance } = require("perf_hooks");
const { ensureKnowledgeDirs, searchFileKnowledge } = require("../plugins/okf/backend/file_knowledge");

const fixtureCount = Math.max(100, Math.min(Number(process.argv[2]) || 1000, 10000));
const queryCount = 120;
const root = fs.mkdtempSync(path.join(os.tmpdir(), "lumi-okf-benchmark-"));
const user = { id: "benchmark-user" };
const admin = { id: "benchmark-admin", isAdmin: true, isMod: true };

try {
  ensureKnowledgeDirs(root);
  const community = path.join(root, "knowledge", "community");
  for (let index = 0; index < fixtureCount; index += 1) {
    const visibility = index % 20 === 0 ? "admin" : "user";
    const secret = visibility === "admin" ? "sealedterm " : "";
    fs.writeFileSync(path.join(community, `fixture-${index}.md`), [
      "---",
      `id: benchmark.fixture-${index}`,
      `title: Benchmark topic ${index}`,
      "scope: community",
      "status: active",
      `visibility: ${visibility}`,
      `priority: ${index % 7}`,
      `tags: benchmark, topic-${index % 50}`,
      "---",
      `# Topic ${index}`,
      `${secret}Support guidance for fixture ${index}, group ${index % 50}, and setting ${index % 17}.`,
      "This paragraph adds enough ordinary text to approximate a small knowledge entry."
    ].join("\n"));
  }

  const coldStart = performance.now();
  const coldResults = searchFileKnowledge({ query: "topic 42 setting", user, rootDir: root, limit: 5 });
  const coldMs = performance.now() - coldStart;
  assert(coldResults.length > 0);

  const timings = [];
  for (let index = 0; index < queryCount; index += 1) {
    const started = performance.now();
    const results = searchFileKnowledge({
      query: `topic ${index % 50} setting ${index % 17}`,
      user,
      rootDir: root,
      limit: 5
    });
    timings.push(performance.now() - started);
    assert(results.length > 0);
  }

  assert.equal(searchFileKnowledge({ query: "sealedterm", user, rootDir: root, limit: 25 }).length, 0);
  assert(searchFileKnowledge({ query: "sealedterm", user: admin, rootDir: root, limit: 25 }).length > 0);

  const changedPath = path.join(community, "fixture-1.md");
  fs.appendFileSync(changedPath, "\nuniquelychangedterm\n");
  assert(searchFileKnowledge({ query: "uniquelychangedterm", user, rootDir: root, limit: 5 }).length > 0);
  fs.rmSync(changedPath);
  assert.equal(searchFileKnowledge({ query: "uniquelychangedterm", user, rootDir: root, limit: 5 }).length, 0);

  timings.sort((a, b) => a - b);
  const percentile = (fraction) => timings[Math.min(timings.length - 1, Math.floor(timings.length * fraction))];
  const result = {
    fixtures: fixtureCount,
    queries: queryCount,
    cold_ms: round(coldMs),
    warm_median_ms: round(percentile(0.5)),
    warm_p95_ms: round(percentile(0.95)),
    warm_max_ms: round(timings[timings.length - 1])
  };
  console.log(JSON.stringify(result, null, 2));
} finally {
  fs.rmSync(root, { recursive: true, force: true });
}

function round(value) {
  return Math.round(value * 100) / 100;
}
