import { getProviderProfile, listProviderProfiles, providerProfileCredentialRef, PROVIDER_PROFILE_KEYS, } from "./providerProfiles.js";
export class ProviderProfileAuthServiceError extends Error {
    code;
    constructor(code, message) {
        super(message);
        this.code = code;
        this.name = "ProviderProfileAuthServiceError";
    }
}
export class ProviderProfileAuthService {
    vault;
    broker;
    audit;
    constructor(vault, broker, audit) {
        this.vault = vault;
        this.broker = broker;
        this.audit = audit;
    }
    listProviderProfiles() {
        return listProviderProfiles();
    }
    async listCredentialStatuses(workspaceId) {
        return Promise.all(PROVIDER_PROFILE_KEYS.map((profileKey) => this.statusApiKey(workspaceId, profileKey)));
    }
    async statusApiKey(workspaceId, profileKey) {
        return toPublicCredentialStatus(await this.statusApiKeyInternal(workspaceId, profileKey));
    }
    async statusApiKeyInternal(workspaceId, profileKey) {
        const profile = requireProviderProfile(profileKey);
        const ref = providerProfileCredentialRef(workspaceId, profile.profileKey);
        return formatInternalCredentialStatus(profile, await this.vault.status(ref));
    }
    validateApiKey(value) {
        normalizeProviderProfileApiKey(value);
    }
    async putApiKey(workspaceId, profileKey, apiKey) {
        return toPublicCredentialStatus(await this.putApiKeyInternal(workspaceId, profileKey, apiKey));
    }
    async putApiKeyInternal(workspaceId, profileKey, apiKey) {
        const profile = requireProviderProfile(profileKey);
        const ref = providerProfileCredentialRef(workspaceId, profile.profileKey);
        const normalized = normalizeProviderProfileApiKey(apiKey);
        const status = await this.vault.put(ref, normalized);
        this.broker.release(ref);
        const formatted = formatInternalCredentialStatus(profile, status);
        this.appendProviderAudit("provider_configured", "provider-configured", {
            profile,
            credentialVersionLabel: "current",
        });
        return formatted;
    }
    async revokeApiKey(workspaceId, profileKey) {
        return toPublicCredentialStatus(await this.revokeApiKeyInternal(workspaceId, profileKey));
    }
    async revokeApiKeyInternal(workspaceId, profileKey) {
        const profile = requireProviderProfile(profileKey);
        const ref = providerProfileCredentialRef(workspaceId, profile.profileKey);
        await this.vault.revoke(ref);
        this.broker.release(ref);
        this.appendProviderAudit("provider_revoked", "provider-revoked", {
            profile,
            credentialVersionLabel: "none",
        });
        return this.statusApiKeyInternal(workspaceId, profile.profileKey);
    }
    appendProviderAudit(type, reasonCode, input) {
        this.audit?.append({
            type,
            severity: "info",
            message: `Provider profile ${type === "provider_configured" ? "configured" : "revoked"}.`,
            metadata: {
                providerProfileKey: input.profile.profileKey,
                provider: input.profile.credentialRef.provider,
                credentialKind: "api_key",
                reasonCode,
                credentialVersionLabel: input.credentialVersionLabel,
                runnable: input.profile.runnable,
                runnableBlockerReason: input.profile.runnableBlockerReason,
            },
        });
    }
}
export function normalizeProviderProfileApiKey(value) {
    const trimmed = value.trim();
    if (!trimmed) {
        throw new ProviderProfileAuthServiceError("invalid_credential", "API key is required.");
    }
    if (trimmed.length > 4_096) {
        throw new ProviderProfileAuthServiceError("invalid_credential", "API key exceeds the 4096 character limit.");
    }
    return trimmed;
}
function requireProviderProfile(profileKey) {
    const profile = getProviderProfile(profileKey);
    if (!profile) {
        throw new ProviderProfileAuthServiceError("provider_profile_not_found", "Provider profile is not supported.");
    }
    return profile;
}
function formatInternalCredentialStatus(profile, status) {
    return {
        profileKey: profile.profileKey,
        displayName: profile.displayName,
        credential: { type: "api_key" },
        runtimeExecutable: profile.runtimeExecutable,
        runnable: profile.runnable,
        runnableBlockerReason: profile.runnableBlockerReason,
        state: status.state,
        ref: status.ref,
        ...(status.maskedLabel ? { maskedLabel: status.maskedLabel } : {}),
        ...(status.updatedAt ? { updatedAt: status.updatedAt } : {}),
        ...(status.backend ? { backend: status.backend } : {}),
        ...(status.degraded !== undefined ? { degraded: status.degraded } : {}),
        ...(status.credentialVersion
            ? { credentialVersion: status.credentialVersion }
            : {}),
    };
}
function toPublicCredentialStatus(status) {
    return {
        profileKey: status.profileKey,
        displayName: status.displayName,
        credential: { ...status.credential },
        runtimeExecutable: status.runtimeExecutable,
        runnable: status.runnable,
        runnableBlockerReason: status.runnableBlockerReason,
        state: status.state,
        ...(status.maskedLabel ? { maskedLabel: status.maskedLabel } : {}),
        ...(status.updatedAt ? { updatedAt: status.updatedAt } : {}),
        ...(status.backend ? { backend: status.backend } : {}),
        ...(status.degraded !== undefined ? { degraded: status.degraded } : {}),
    };
}
