import assert from "node:assert/strict";
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { afterEach, describe, test } from "vitest";
import { runProviderChecks } from "../doctor-providers.js";
import { PROVIDER_REGISTRY } from "../key-manager.js";

const originalCwd = process.cwd();
const originalEnv = { ...process.env };
const tmpDirs = [];

afterEach(() => {
	process.chdir(originalCwd);
	process.env = { ...originalEnv };
	while (tmpDirs.length > 0) {
		rmSync(tmpDirs.pop(), { recursive: true, force: true });
	}
});

function makePreferencesProject(globalPreferences) {
	const root = mkdtempSync(join(tmpdir(), "sf-doctor-providers-"));
	tmpDirs.push(root);
	const home = join(root, "home");
	const project = join(root, "project");
	mkdirSync(home, { recursive: true });
	mkdirSync(join(home, ".sf", "agent"), { recursive: true });
	mkdirSync(join(project, ".sf"), { recursive: true });
	writeFileSync(join(home, "preferences.yaml"), globalPreferences, "utf-8");
	writeFileSync(
		join(project, ".sf", "preferences.yaml"),
		"version: 1\nmodels: {}\n",
		"utf-8",
	);
	process.env.SF_HOME = home;
	process.env.HOME = home;
	process.chdir(project);
	return project;
}

describe("doctor provider checks", () => {
	test("provider registry includes direct routed model providers used by SF preferences", () => {
		const providers = new Map(PROVIDER_REGISTRY.map((p) => [p.id, p]));

		assert.equal(providers.get("minimax")?.envVar, "MINIMAX_API_KEY");
		assert.equal(providers.get("kimi-coding")?.envVar, "KIMI_API_KEY");
	});

	test("runProviderChecks_when_any_configured_llm_route_is_usable_does_not_require_every_preferred_provider", () => {
		makePreferencesProject(
			[
				"version: 1",
				"models:",
				"  execution: kimi-coding/kimi-k2.6",
				"  reassess: mistral/devstral-latest",
				"",
			].join("\n"),
		);
		process.env.KIMI_API_KEY = "test-kimi-key";
		delete process.env.MISTRAL_API_KEY;

		const results = runProviderChecks();
		const mistral = results.find((result) => result.name === "mistral");

		assert.equal(mistral?.status, "unconfigured");
		assert.equal(mistral?.required, false);
	});

	test("runProviderChecks_when_remote_questions_auto_resolve_does_not_require_channel_token", () => {
		makePreferencesProject(
			[
				"version: 1",
				"models:",
				"  execution: kimi-coding/kimi-k2.6",
				"remote_questions:",
				"  channel: telegram",
				"  channel_id: 562797207",
				"  auto_resolve_on_timeout: true",
				"  auto_resolve_strategy: recommended-option",
				"",
			].join("\n"),
		);
		process.env.KIMI_API_KEY = "test-kimi-key";
		delete process.env.TELEGRAM_BOT_TOKEN;

		const results = runProviderChecks();
		const telegram = results.find((result) => result.name === "telegram_bot");

		assert.equal(telegram?.status, "unconfigured");
		assert.equal(telegram?.required, false);
	});

	test("runProviderChecks_when_google_env_auth_is_default_off_treats_google_as_missing_required_route", () => {
		makePreferencesProject(
			["version: 1", "models:", "  planning: google/gemini-2.5-pro", ""].join(
				"\n",
			),
		);
		process.env.GEMINI_API_KEY = "test-google-key";

		const results = runProviderChecks();
		const google = results.find((result) => result.name === "google");

		assert.equal(google?.status, "error");
	});

	test("runProviderChecks_when_google_env_auth_is_enabled_accepts_google_env_key", () => {
		const project = makePreferencesProject(
			["version: 1", "models:", "  planning: google/gemini-2.5-pro", ""].join(
				"\n",
			),
		);
		mkdirSync(join(project, ".sf"), { recursive: true });
		writeFileSync(
			join(project, ".sf", "settings.json"),
			JSON.stringify(
				{
					providerEnvAuth: {
						providers: {
							google: "on",
						},
					},
				},
				null,
				2,
			),
			"utf-8",
		);
		process.env.GEMINI_API_KEY = "test-google-key";

		const results = runProviderChecks();
		const google = results.find((result) => result.name === "google");

		assert.equal(google?.status, "ok");
		assert.equal(google?.source, "env");
	});
});
