// SF2 — Read-only query tools exposing DB state to the LLM via the WAL connection
import { Type } from "@sinclair/typebox";
import { getRetrievalEvidence } from "../sf-db.js";
import { executeMilestoneStatus } from "../tools/workflow-tool-executors.js";
import { ensureDbOpen } from "./dynamic-tools.js";
export function registerQueryTools(pi) {
	pi.registerTool({
		name: "milestone_status",
		label: "Milestone Status",
		description:
			"Read the current status of a milestone and all its slices from the SF database. " +
			"Returns milestone metadata, per-slice status, and task counts per slice. " +
			"Use this instead of querying .sf/sf.db directly via sqlite3 or better-sqlite3.",
		promptSnippet:
			"Get milestone status, slice statuses, and task counts for a given milestoneId",
		promptGuidelines: [
			"Use this tool — not sqlite3 or better-sqlite3 — to inspect milestone or slice state from the DB.",
		],
		parameters: Type.Object({
			milestoneId: Type.String({
				description: "Milestone ID to query (e.g. M001)",
			}),
		}),
		async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
			const dbAvailable = await ensureDbOpen();
			if (!dbAvailable) {
				return {
					content: [
						{
							type: "text",
							text: "Error: SF database is not available. Cannot read milestone status.",
						},
					],
					details: { operation: "milestone_status", error: "db_unavailable" },
				};
			}
			return executeMilestoneStatus(params);
		},
	});
	pi.registerTool({
		name: "search_evidence",
		label: "Retrieval Evidence",
		description:
			"Search the retrieval evidence log and return metadata about prior information lookups — source backend, query, scope, freshness, and status. " +
			"Use this to audit where retrieved context came from or to check whether a search has already been performed.",
		promptSnippet:
			"Inspect recent retrieval evidence rows with backend, scope, freshness, and hit counts",
		promptGuidelines: [
			"Use this to verify whether context came from live source, stale indexed docs, or another retrieval backend before trusting it.",
			"Prefer rows with backend=sift and freshness=working-tree/git-head for implementation decisions.",
		],
		parameters: Type.Object({
			limit: Type.Optional(
				Type.Number({
					description: "Maximum number of retrieval evidence rows to return.",
					default: 20,
				}),
			),
		}),
		async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
			const dbAvailable = await ensureDbOpen();
			if (!dbAvailable) {
				return {
					content: [
						{
							type: "text",
							text: "Error: SF database is not available. Cannot read retrieval evidence.",
						},
					],
					details: {
						operation: "retrieval_evidence",
						error: "db_unavailable",
					},
				};
			}
			const limit = Math.max(1, Math.min(100, params.limit ?? 20));
			const rows = getRetrievalEvidence(limit);
			const lines = [`Retrieval evidence: ${rows.length} row(s)`, ""];
			for (const row of rows) {
				lines.push(
					`- #${row.id} ${row.backend}/${row.sourceKind} ${row.status} ` +
						`freshness=${row.freshness} scope=${row.scope || "."} hits=${row.hitCount} ` +
						`query="${row.query}"`,
				);
			}
			return {
				content: [{ type: "text", text: lines.join("\n") }],
				details: {
					operation: "retrieval_evidence",
					rows,
				},
			};
		},
	});
}
