import { EventEmitter } from 'node:events';
/**
 * 마이그레이션 진행 상황을 브로드캐스트하는 서비스
 * - 런 ID별 최신 스냅샷을 캐시하고 구독자에게 실시간으로 전달
 */
class MigrationMonitorService {
    emitter = new EventEmitter();
    latestEvents = new Map();
    statuses = new Map();
    allChannel = 'migration-progress';
    publish(event) {
        const clonedEvent = this.cloneEvent(event);
        this.latestEvents.set(event.runId, clonedEvent);
        this.statuses.set(event.runId, event.status);
        this.emitter.emit(this.channel(event.runId), clonedEvent);
        this.emitter.emit(this.allChannel, clonedEvent);
    }
    subscribe(runId, listener) {
        const channel = this.channel(runId);
        const handler = (event) => {
            listener(this.cloneEvent(event));
        };
        this.emitter.on(channel, handler);
        const latest = this.latestEvents.get(runId);
        if (latest) {
            listener(this.cloneEvent(latest));
        }
        return () => {
            this.emitter.off(channel, handler);
        };
    }
    subscribeAll(listener) {
        const handler = (event) => {
            listener(this.cloneEvent(event));
        };
        this.emitter.on(this.allChannel, handler);
        return () => {
            this.emitter.off(this.allChannel, handler);
        };
    }
    getLatest(runId) {
        const latest = this.latestEvents.get(runId);
        return latest ? this.cloneEvent(latest) : undefined;
    }
    getStatus(runId) {
        return this.statuses.get(runId);
    }
    listActiveRuns() {
        return Array.from(this.statuses.entries())
            .filter(([, status]) => status === 'running')
            .map(([runId]) => runId);
    }
    clear(runId) {
        this.latestEvents.delete(runId);
        this.statuses.delete(runId);
    }
    channel(runId) {
        return `migration-progress:${runId}`;
    }
    cloneEvent(event) {
        return {
            runId: event.runId,
            status: event.status,
            timestamp: new Date(event.timestamp),
            progress: this.cloneProgress(event.progress)
        };
    }
    cloneProgress(progress) {
        return {
            total: progress.total,
            processed: progress.processed,
            succeeded: progress.succeeded,
            failed: progress.failed,
            startedAt: new Date(progress.startedAt),
            updatedAt: new Date(progress.updatedAt),
            lastMemoryId: progress.lastMemoryId,
            currentStep: progress.currentStep
                ? {
                    ...progress.currentStep,
                    startedAt: progress.currentStep.startedAt ? new Date(progress.currentStep.startedAt) : undefined,
                    completedAt: progress.currentStep.completedAt ? new Date(progress.currentStep.completedAt) : undefined
                }
                : undefined,
            stepHistory: progress.stepHistory.map(step => ({
                ...step,
                startedAt: step.startedAt ? new Date(step.startedAt) : undefined,
                completedAt: step.completedAt ? new Date(step.completedAt) : undefined
            }))
        };
    }
}
export const migrationMonitorService = new MigrationMonitorService();
//# sourceMappingURL=migration-monitor-service.js.map