import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
import { init_write_file_atomic, writeTextAtomic } from "../infra/write-file-atomic.js";
import { createLogger } from "../utils/logger/index.js";
import { init_logger } from "../utils/logger.js";
import { getApiKeyFromEnv, init_env_keys } from "../providers/env-keys.js";
import { init_paths, resolveAgentAuthProfilesPath, resolveAuthProfilesPath, resolveCredentialsDir, resolveOAuthPath } from "../config/paths.js";
import { mkdir, readFile } from "fs/promises";
import { dirname, join } from "path";
//#region src/auth/credentials.ts
function getCredentialResolver(options) {
	return new CredentialResolver(options);
}
async function resolveApiKey(provider, options) {
	return getCredentialResolver(options).resolveApiKey(provider);
}
async function hasCredentials(provider, options) {
	return getCredentialResolver(options).hasCredentials(provider);
}
var log, CredentialResolver;
var init_credentials = __esmMin((() => {
	init_write_file_atomic();
	init_logger();
	init_env_keys();
	init_paths();
	log = createLogger("Credentials");
	CredentialResolver = class {
		credentialsDir;
		agentId;
		appConfig;
		constructor(options = {}) {
			this.credentialsDir = options.stateDir ? join(options.stateDir, "credentials") : resolveCredentialsDir();
			this.agentId = options.agentId;
			this.appConfig = options.appConfig;
			if (this.agentId && !this.appConfig) throw new Error("CredentialResolver: appConfig is required when agentId is set");
		}
		/**
		* Resolve API key for a provider
		* Priority: Agent private > Global > OAuth > Environment
		*/
		async resolveApiKey(provider) {
			const normalizedProvider = provider.toLowerCase();
			if (this.agentId) {
				const agentKey = await this.loadFromAgentCredentials(normalizedProvider);
				if (agentKey) {
					log.debug({
						provider,
						source: "agent"
					}, "Resolved API key from agent credentials");
					return agentKey;
				}
			}
			const globalKey = await this.loadFromGlobalCredentials(normalizedProvider);
			if (globalKey) {
				log.debug({
					provider,
					source: "global"
				}, "Resolved API key from global credentials");
				return globalKey;
			}
			const oauthToken = await this.loadOAuthToken(normalizedProvider);
			if (oauthToken) {
				log.debug({
					provider,
					source: "oauth"
				}, "Resolved API key from OAuth token");
				return oauthToken.access;
			}
			const envKey = getApiKeyFromEnv(normalizedProvider);
			if (envKey) {
				log.debug({
					provider,
					source: "env"
				}, "Resolved API key from environment");
				return envKey;
			}
			log.debug({ provider }, "No API key found");
			return null;
		}
		/**
		* Check if a provider has credentials configured
		*/
		async hasCredentials(provider) {
			return await this.resolveApiKey(provider) !== null;
		}
		/**
		* Which step in {@link resolveApiKey} would supply the key (no secret material).
		*/
		async resolveApiKeySource(provider) {
			const normalizedProvider = provider.toLowerCase();
			if (this.agentId) {
				if (await this.loadFromAgentCredentials(normalizedProvider)) return "agent";
			}
			if (await this.loadFromGlobalCredentials(normalizedProvider)) return "global";
			if (await this.loadOAuthToken(normalizedProvider)) return "oauth";
			if (getApiKeyFromEnv(normalizedProvider)) return "env";
			return null;
		}
		/**
		* List all available credential profiles
		*/
		async listProfiles() {
			const profiles = [];
			const globalProfiles = await this.loadAuthProfilesFile();
			for (const [id, profile] of Object.entries(globalProfiles.profiles)) profiles.push({
				...profile,
				id,
				source: "global"
			});
			if (this.agentId) {
				const agentProfiles = await this.loadAgentAuthProfilesFile();
				for (const [id, profile] of Object.entries(agentProfiles.profiles)) profiles.push({
					...profile,
					id,
					source: "agent"
				});
			}
			return profiles;
		}
		/**
		* Plaintext API key from global auth profiles only (no env/oauth fallback).
		* Used by the gateway console reveal endpoint.
		*/
		async revealGatewayStoredApiKey(provider) {
			const normalizedProvider = provider.toLowerCase();
			const profiles = await this.loadAuthProfilesFile();
			return this.findProfileForProvider(profiles, normalizedProvider)?.key?.trim() || null;
		}
		/**
		* Save an API key profile
		*/
		async saveApiKey(provider, key, options = {}) {
			const normalizedProvider = provider.toLowerCase();
			const profileId = options.profileName ? `${normalizedProvider}:${options.profileName}` : `${normalizedProvider}:default`;
			const profile = {
				type: "api_key",
				provider: normalizedProvider,
				profileName: options.profileName,
				envVar: options.envVar ?? null,
				key
			};
			if (options.agentPrivate && this.agentId) await this.saveAgentAuthProfile(profileId, profile);
			else await this.saveGlobalAuthProfile(profileId, profile);
			log.info({
				provider,
				profileId,
				agentPrivate: options.agentPrivate
			}, "Saved API key");
		}
		/**
		* Delete a credential profile
		*/
		async deleteProfile(profileId, options = {}) {
			if (options.agentPrivate && this.agentId) await this.deleteAgentAuthProfile(profileId);
			else await this.deleteGlobalAuthProfile(profileId);
			log.info({
				profileId,
				agentPrivate: options.agentPrivate
			}, "Deleted credential profile");
		}
		/**
		* Load OAuth token for a provider
		*/
		async loadOAuthToken(provider) {
			const oauthPath = resolveOAuthPath(provider.toLowerCase());
			try {
				const content = await readFile(oauthPath, "utf-8");
				const token = JSON.parse(content);
				if (token.expiresAt && token.expiresAt < Date.now()) {
					log.warn({
						provider,
						expiresAt: token.expiresAt
					}, "OAuth token is expired");
					return null;
				}
				return token;
			} catch {
				return null;
			}
		}
		/**
		* Save OAuth token for a provider
		*/
		async saveOAuthToken(provider, token) {
			const normalizedProvider = provider.toLowerCase();
			const oauthPath = resolveOAuthPath(normalizedProvider);
			await mkdir(dirname(oauthPath), { recursive: true });
			const fullToken = {
				...token,
				type: "oauth",
				provider: normalizedProvider,
				updatedAt: (/* @__PURE__ */ new Date()).toISOString()
			};
			await writeTextAtomic(oauthPath, JSON.stringify(fullToken, null, 2));
			log.info({ provider }, "Saved OAuth token");
		}
		async loadFromAgentCredentials(provider) {
			if (!this.agentId) return null;
			const profiles = await this.loadAgentAuthProfilesFile();
			const profile = this.findProfileForProvider(profiles, provider);
			if (!profile) return null;
			if (profile.envVar) return this.loadFromEnv(profile.envVar) ?? profile.key;
			return profile.key;
		}
		async loadFromGlobalCredentials(provider) {
			const profiles = await this.loadAuthProfilesFile();
			const profile = this.findProfileForProvider(profiles, provider);
			if (!profile) return null;
			if (profile.envVar) return this.loadFromEnv(profile.envVar) ?? profile.key;
			return profile.key;
		}
		loadFromEnv(envVarName) {
			return process.env[envVarName] || null;
		}
		findProfileForProvider(file, provider) {
			const normalizedProvider = provider.toLowerCase();
			for (const [, profile] of Object.entries(file.profiles)) if (profile.provider === normalizedProvider) return profile;
			return null;
		}
		async loadAuthProfilesFile() {
			const path = resolveAuthProfilesPath();
			try {
				const content = await readFile(path, "utf-8");
				const data = JSON.parse(content);
				return {
					version: data.version || 1,
					profiles: data.profiles || {}
				};
			} catch {
				return {
					version: 2,
					profiles: {}
				};
			}
		}
		async loadAgentAuthProfilesFile() {
			if (!this.agentId || !this.appConfig) return {
				version: 2,
				profiles: {}
			};
			const path = resolveAgentAuthProfilesPath(this.appConfig, this.agentId);
			try {
				const content = await readFile(path, "utf-8");
				const data = JSON.parse(content);
				return {
					version: data.version || 1,
					profiles: data.profiles || {}
				};
			} catch {
				return {
					version: 2,
					profiles: {}
				};
			}
		}
		async saveGlobalAuthProfile(profileId, profile) {
			const path = resolveAuthProfilesPath();
			await mkdir(dirname(path), { recursive: true });
			const file = await this.loadAuthProfilesFile();
			file.profiles[profileId] = profile;
			await writeTextAtomic(path, JSON.stringify(file, null, 2));
		}
		async saveAgentAuthProfile(profileId, profile) {
			if (!this.agentId || !this.appConfig) throw new Error("Agent ID and appConfig required for agent-private profiles");
			const path = resolveAgentAuthProfilesPath(this.appConfig, this.agentId);
			await mkdir(dirname(path), { recursive: true });
			const file = await this.loadAgentAuthProfilesFile();
			file.profiles[profileId] = profile;
			await writeTextAtomic(path, JSON.stringify(file, null, 2));
		}
		async deleteGlobalAuthProfile(profileId) {
			const path = resolveAuthProfilesPath();
			const file = await this.loadAuthProfilesFile();
			delete file.profiles[profileId];
			await writeTextAtomic(path, JSON.stringify(file, null, 2));
		}
		async deleteAgentAuthProfile(profileId) {
			if (!this.agentId || !this.appConfig) throw new Error("Agent ID and appConfig required for agent-private profiles");
			const path = resolveAgentAuthProfilesPath(this.appConfig, this.agentId);
			const file = await this.loadAgentAuthProfilesFile();
			delete file.profiles[profileId];
			await writeTextAtomic(path, JSON.stringify(file, null, 2));
		}
	};
}));
//#endregion
init_credentials();
export { CredentialResolver, getCredentialResolver, hasCredentials, init_credentials, resolveApiKey };

//# sourceMappingURL=credentials.js.map