// engine/llm-providers/provider-adapter.ts — Provider adapter interface + factory.
// SPEC-083 AC-02
import { checkApiKey } from './key-manager.js';
/**
 * Base adapter implementation shared by all providers.
 * Validates config and reports status without making real API calls.
 */
export class BaseProviderAdapter {
    providerId;
    definition;
    constructor(definition) {
        this.providerId = definition.id;
        this.definition = definition;
    }
    checkHealth() {
        const apiKeyStatus = this.getApiKeyStatus();
        const status = apiKeyStatus === 'configured'
            ? 'healthy'
            : apiKeyStatus === 'invalid_format'
                ? 'degraded'
                : 'unavailable';
        return {
            providerId: this.providerId,
            status,
            apiKeyStatus,
            lastChecked: new Date().toISOString(),
            details: this.buildHealthDetails(apiKeyStatus),
        };
    }
    getModels() {
        return this.definition.models;
    }
    estimateCost(inputTokens, outputTokens, modelId) {
        const model = modelId
            ? this.definition.models.find((m) => m.id === modelId)
            : this.definition.models[0];
        if (!model) {
            return 0;
        }
        const inputCost = (inputTokens / 1_000_000) * model.pricingPerMToken.input;
        const outputCost = (outputTokens / 1_000_000) * model.pricingPerMToken.output;
        return inputCost + outputCost;
    }
    getStatus() {
        return this.checkHealth();
    }
    getApiKeyStatus() {
        return checkApiKey(this.definition.apiKeyEnv, this.definition.keyPattern);
    }
    buildHealthDetails(keyStatus) {
        if (keyStatus === 'configured') {
            return `${this.definition.name} is configured and ready.`;
        }
        if (keyStatus === 'invalid_format') {
            return `${this.definition.name} API key is present but has unexpected format.`;
        }
        return `${this.definition.name} API key (${this.definition.apiKeyEnv}) is not set.`;
    }
}
/** Ollama-specific adapter: no API key required, checks local port. */
export class OllamaAdapter extends BaseProviderAdapter {
    checkHealth() {
        // Ollama doesn't require an API key; check if port config is set
        const isLocal = this.definition.baseUrl.includes('localhost') ||
            this.definition.baseUrl.includes('127.0.0.1');
        return {
            providerId: this.providerId,
            status: isLocal ? 'healthy' : 'degraded',
            apiKeyStatus: 'configured',
            lastChecked: new Date().toISOString(),
            details: isLocal
                ? 'Ollama configured for local usage (port 11434). No API key required.'
                : 'Ollama configured with non-local URL. Verify connectivity.',
        };
    }
}
/**
 * Factory function to create the appropriate adapter for a provider.
 */
export function createProviderAdapter(definition) {
    if (definition.id === 'ollama') {
        return new OllamaAdapter(definition);
    }
    return new BaseProviderAdapter(definition);
}
//# sourceMappingURL=provider-adapter.js.map