import assert from "node:assert/strict";
import { afterEach, beforeEach, describe, it } from 'vitest';
import type { Model } from "@singularity-forge/pi-ai";
import type { ModelRegistry } from "../core/model-registry.js";
import { listModels } from "./list-models.js";

const model = (provider: string, id: string): Model<any> => ({
	id,
	name: id,
	api: "openai-completions",
	provider,
	baseUrl: "https://example.invalid",
	reasoning: false,
	input: ["text"],
	cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
	contextWindow: 128000,
	maxTokens: 16000,
});

let originalLog: typeof console.log;
let output: string[];

beforeEach(() => {
	originalLog = console.log;
	output = [];
	console.log = (...args: unknown[]) => {
		output.push(args.join(" "));
	};
});

afterEach(() => {
	console.log = originalLog;
});

describe("listModels", () => {
	it("exact live provider search uses discovery and replaces static rows", async () => {
		const registry = {
			discoverModels: async (providers?: string[]) => {
				assert.deepEqual(providers, ["zai"]);
				return [{ provider: "zai", models: [{ id: "glm-5.1" }], fetchedAt: Date.now() }];
			},
			getAvailable: () => [model("zai", "glm-4.5-air"), model("zai", "glm-5.1")],
			getDiscoveredModels: () => [model("zai", "glm-5.1")],
			isDiscovered: (m: Model<any>) => m.provider === "zai" && m.id === "glm-5.1",
		} as unknown as ModelRegistry;

		await listModels(registry, { searchPattern: "zai" });

		const rendered = output.join("\n");
		assert.match(rendered, /glm-5\.1/);
		assert.doesNotMatch(rendered, /glm-4\.5-air/);
	});

	it("discovery errors hide stale static rows for attempted live providers", async () => {
		const registry = {
			discoverModels: async () => [
				{ provider: "zai", models: [], fetchedAt: Date.now(), error: "401 Unauthorized" },
			],
			getAvailable: () => [model("zai", "glm-5.1"), model("minimax", "MiniMax-M2.7")],
			getDiscoveredModels: () => [],
			isDiscovered: () => false,
		} as unknown as ModelRegistry;

		await listModels(registry, { discover: true });

		const rendered = output.join("\n");
		assert.doesNotMatch(rendered, /zai/);
		assert.match(rendered, /MiniMax-M2\.7/);
	});
});
