import { CarrierApi } from './carrier-types'; import { TwilioCarrier } from './twilio-carrier'; import { PlivoCarrier } from './plivo-carrier'; export type CarrierType = 'twilio' | 'plivo' | 'sip'; export interface CarrierFactoryConfig { twilio?: { apiKey: string; apiSecret: string; accountSid: string; apiBaseUrl?: string; decisionTimeout?: number; }; plivo?: { authId: string; authToken: string; apiBaseUrl?: string; decisionTimeout?: number; }; defaultDecisionTimeout?: number; } export class CarrierFactory { private readonly config: CarrierFactoryConfig; private readonly carriers: Map = new Map(); constructor(config: CarrierFactoryConfig) { this.config = { defaultDecisionTimeout: 200, ...config, }; } createCarrier(type: CarrierType): CarrierApi { const cached = this.carriers.get(type); if (cached) { return cached; } const carrier = this.instantiateCarrier(type); this.carriers.set(type, carrier); return carrier; } async validateCarrier(type: CarrierType): Promise { const carrier = this.createCarrier(type); return carrier.isHealthy(); } async getCarrierMetrics(type: CarrierType): Promise<{ type: CarrierType; healthy: boolean; latency: number; }> { const carrier = this.createCarrier(type); const startTime = Date.now(); const healthy = await carrier.isHealthy(); const latency = Date.now() - startTime; return { type, healthy, latency }; } private instantiateCarrier(type: CarrierType): CarrierApi { switch (type) { case 'twilio': if (!this.config.twilio) { throw new Error('Twilio configuration not provided'); } return new TwilioCarrier({ ...this.config.twilio, decisionTimeout: this.config.twilio.decisionTimeout ?? this.config.defaultDecisionTimeout, }); case 'plivo': if (!this.config.plivo) { throw new Error('Plivo configuration not provided'); } return new PlivoCarrier({ ...this.config.plivo, decisionTimeout: this.config.plivo.decisionTimeout ?? this.config.defaultDecisionTimeout, }); case 'sip': // SIP carrier would be implemented separately throw new Error('SIP carrier not yet implemented'); default: throw new Error(`Unknown carrier type: ${type}`); } } async getAllCarriers(): Promise> { const results: Array<{ type: CarrierType; healthy: boolean }> = []; for (const [type, carrier] of this.carriers.entries()) { const healthy = await carrier.isHealthy(); results.push({ type, healthy, }); } return results; } clearCache(): void { this.carriers.clear(); } }