import { test } from "node:test";
import assert from "node:assert/strict";
import { rankVocab } from "./vocab-rank.js";

const vocab = {
  cvars: [
    { name: "sv_cheats", desc: "Allow cheats" },
    { name: "sv_gravity" },
    { name: "mp_friendlyfire", desc: "Toggle FF" },
  ],
  commands: [
    { name: "kick", desc: "Kick a player" },
    { name: "kickall", desc: "Kick everyone" },
    { name: "changelevel", desc: "Change map" },
  ],
};

test("exact match comes first", () => {
  const out = rankVocab("kick", vocab);
  assert.equal(out[0].name, "kick");
  assert.equal(out[1].name, "kickall");
});

test("prefix matches beat substring matches", () => {
  const out = rankVocab("sv_", vocab);
  assert.equal(out[0].name, "sv_cheats");
  assert.equal(out[1].name, "sv_gravity");
  // mp_friendlyfire contains no "sv_" → should not appear
  assert.ok(!out.some(e => e.name === "mp_friendlyfire"));
});

test("substring matches included after prefix matches", () => {
  // "iendly" is a substring of mp_friendlyfire but a prefix of nothing
  const out = rankVocab("iendly", vocab);
  assert.equal(out.length, 1);
  assert.equal(out[0].name, "mp_friendlyfire");
});

test("kind is preserved on each result", () => {
  const out = rankVocab("kick", vocab);
  assert.equal(out[0].kind, "command");
  const sv = rankVocab("sv_cheats", vocab);
  assert.equal(sv[0].kind, "cvar");
});

test("desc is preserved when present", () => {
  const out = rankVocab("kick", vocab);
  assert.equal(out[0].desc, "Kick a player");
});

test("desc is undefined when source had no desc", () => {
  const out = rankVocab("sv_gravity", vocab);
  assert.equal(out[0].desc, undefined);
});

test("results are capped at the configured limit", () => {
  const big = { cvars: [], commands: [] };
  for (let i = 0; i < 200; i++) big.commands.push({ name: `cmd${i}` });
  const out = rankVocab("cmd", big, { limit: 50 });
  assert.equal(out.length, 50);
});

test("default limit is 50", () => {
  const big = { cvars: [], commands: [] };
  for (let i = 0; i < 200; i++) big.commands.push({ name: `cmd${i}` });
  const out = rankVocab("cmd", big);
  assert.equal(out.length, 50);
});

test("empty query returns no results", () => {
  const out = rankVocab("", vocab);
  assert.equal(out.length, 0);
});

test("case-insensitive match", () => {
  const out = rankVocab("KICK", vocab);
  assert.equal(out[0].name, "kick");
});
