import { existsSync, readFileSync } from "node:fs";
import { join } from "node:path";
import { getEnvApiKey } from "@singularity-forge/ai";
import { getAgentDir, SettingsManager } from "@singularity-forge/coding-agent";

function readJson(path) {
	try {
		if (!existsSync(path)) return {};
		return JSON.parse(readFileSync(path, "utf-8"));
	} catch {
		return {};
	}
}

function readProviderEnvAuthSettings(cwd, agentDir) {
	const globalSettings = readJson(join(agentDir, "settings.json"));
	const projectSettings = readJson(join(cwd, ".sf", "settings.json"));
	return {
		...(globalSettings.providerEnvAuth ?? {}),
		...(projectSettings.providerEnvAuth ?? {}),
		providers: {
			...(globalSettings.providerEnvAuth?.providers ?? {}),
			...(projectSettings.providerEnvAuth?.providers ?? {}),
		},
	};
}

function getProviderEnvAuthMode(providerId, cwd) {
	const agentDir = getAgentDir();
	const settingsManager = SettingsManager.create(cwd, agentDir);
	if (typeof settingsManager.getProviderEnvAuthMode === "function") {
		return settingsManager.getProviderEnvAuthMode(providerId);
	}
	const settings = readProviderEnvAuthSettings(cwd, agentDir);
	// Default: "off" — env var keys are ignored unless explicitly enabled per provider.
	// Set providerEnvAuth.providers.<id> = "auto" in settings.json to opt in.
	return settings.providers?.[providerId] ?? settings.default ?? "off";
}

/**
 * Returns true if env-var auth is allowed for this provider.
 * Env auth is off by default — opt in via providerEnvAuth.providers.<id> = "auto"
 * in ~/.sf/agent/settings.json or .sf/settings.json.
 */
export function isEnvAuthAllowed(providerId, cwd = process.cwd()) {
	return getProviderEnvAuthMode(providerId, cwd) !== "off";
}

function getProviderEnvKey(providerId) {
	const apiKey = getEnvApiKey(providerId);
	if (apiKey) return apiKey;
	if (providerId === "google") {
		return (
			process.env.GEMINI_API_KEY || process.env.GOOGLE_GENERATIVE_AI_API_KEY
		);
	}
	return undefined;
}

/**
 * Return the provider env API key only when Forge settings allow env auth.
 *
 * Covers SDK-known providers (via getEnvApiKey) and Google variants.
 * For SF-specific providers (search, tool), use getGatedEnvVarKey instead.
 */
export function getConfiguredEnvApiKey(providerId, cwd = process.cwd()) {
	if (!isEnvAuthAllowed(providerId, cwd)) return undefined;
	return getProviderEnvKey(providerId);
}

/**
 * Return the value of a specific env var only when env auth is allowed for that provider.
 *
 * Purpose: gate SF-specific providers (Brave, Tavily, Serper, Exa, etc.) that are
 * not covered by the SDK's getEnvApiKey but whose envVar is known from PROVIDER_REGISTRY.
 *
 * Consumer: doctor-providers.js fallback path for search/tool providers.
 */
export function getGatedEnvVarKey(providerId, envVarName, cwd = process.cwd()) {
	if (!isEnvAuthAllowed(providerId, cwd)) return undefined;
	const value = process.env[envVarName];
	return value && value.trim() ? value : undefined;
}
