import assert from "node:assert/strict";
import test from "node:test";

import type { ToolInfo } from "@earendil-works/pi-coding-agent";
import { BUNDLE_GROUP_DEFINITIONS, createBundleCatalog } from "../extensions/bundle-groups.ts";
import { buildManifestHash } from "../extensions/catalog.ts";

function tool(name: string): ToolInfo {
  return {
    name,
    description: `Full description for ${name}`,
    parameters: { type: "object", properties: {} } as ToolInfo["parameters"],
    sourceInfo: { source: "extension", scope: "user", path: `/test/${name}.ts` } as unknown as ToolInfo["sourceInfo"],
  };
}

const constraints = { maxToolsPerGroup: 8, groupOverrides: {} };

test("bundle seed names are unique and cover the declared my-pi tools", () => {
  const names = BUNDLE_GROUP_DEFINITIONS.flatMap((group) => group.tools);
  assert.equal(new Set(names).size, names.length);
  const tools = names.map(tool);
  const hash = buildManifestHash(tools, constraints);
  const result = createBundleCatalog(tools, hash, constraints);
  assert.deepEqual(result.unknownTools, []);
  assert.equal(result.coveredNames.size, names.length);
  assert.equal(result.catalog.tools.length, names.length);
  assert.equal(result.catalog.tools.find((card) => card.name === "ctx_purge")?.primaryGroup, "context-administration");
  assert.equal(result.catalog.tools.find((card) => card.name === "tavily_web_fetch")?.primaryGroup, "web-tavily");
  assert.equal(result.catalog.tools.find((card) => card.name === "hippo_recall")?.primaryGroup, "memory-recall");
  assert.equal(result.catalog.tools.find((card) => card.name === "hippo_remember")?.primaryGroup, "memory-management");
});

test("user overrides take priority and unknown tools retain deterministic fallback groups", () => {
  const tools = [tool("tavily_web_search"), tool("custom_analyze")];
  const configured = { maxToolsPerGroup: 8, groupOverrides: { preferred: ["tavily_web_search"] } };
  const hash = buildManifestHash(tools, configured);
  const result = createBundleCatalog(tools, hash, configured);
  assert.deepEqual(result.unknownTools.map((item) => item.name), ["custom_analyze"]);
  assert.equal(result.catalog.tools.find((card) => card.name === "tavily_web_search")?.primaryGroup, "preferred");
  assert.equal(result.catalog.tools.find((card) => card.name === "custom_analyze")?.primaryGroup, "custom");
});
