import { isTerminalActivityStatus } from '../../types/activity/index.js';
import { generateActivityId } from '../../utils/id.js';
export class ActivityStore {
    activities = new Map();
    runId;
    config;
    listeners = [];
    constructor(runId, config) {
        this.runId = runId;
        this.config = config;
    }
    get enabled() {
        return this.config.enabled;
    }
    on(listener) {
        this.listeners.push(listener);
        return () => {
            this.listeners = this.listeners.filter((l) => l !== listener);
        };
    }
    emit(event) {
        for (const listener of this.listeners) {
            try {
                listener(event);
            }
            catch { }
        }
    }
    create(params) {
        if (!this.config.enabled)
            return null;
        if (params.type === 'tool_call' && !this.config.trackToolCalls)
            return null;
        if (params.type === 'llm_turn' && !this.config.trackLlmTurns)
            return null;
        const activity = {
            id: generateActivityId(),
            runId: this.runId,
            type: params.type,
            status: 'pending',
            description: params.description,
            input: params.input,
            parentActivityId: params.parentActivityId,
            toolName: params.toolName,
            toolCallId: params.toolCallId,
            blockedBy: params.blockedBy ?? [],
            blocks: [],
            createdAt: Date.now(),
        };
        this.activities.set(activity.id, activity);
        if (params.blockedBy) {
            for (const blockerId of params.blockedBy) {
                const blocker = this.activities.get(blockerId);
                if (blocker) {
                    blocker.blocks.push(activity.id);
                }
            }
        }
        this.emit({ type: 'activity.created', activity });
        return activity;
    }
    start(activityId) {
        const activity = this.activities.get(activityId);
        if (!activity || activity.status !== 'pending')
            return null;
        const unblockedDeps = activity.blockedBy.filter((depId) => {
            const dep = this.activities.get(depId);
            return dep && !isTerminalActivityStatus(dep.status);
        });
        if (unblockedDeps.length > 0)
            return null;
        activity.status = 'running';
        activity.startedAt = Date.now();
        this.emit({ type: 'activity.started', activity });
        return activity;
    }
    updateProgress(activityId, progress) {
        const activity = this.activities.get(activityId);
        if (!activity || activity.status !== 'running')
            return null;
        activity.progress = { ...progress, updatedAt: Date.now() };
        this.emit({ type: 'activity.progress', activity });
        return activity;
    }
    complete(activityId, output) {
        const activity = this.activities.get(activityId);
        if (!activity || isTerminalActivityStatus(activity.status))
            return null;
        activity.status = 'completed';
        activity.output = output;
        activity.completedAt = Date.now();
        activity.durationMs = activity.startedAt ? activity.completedAt - activity.startedAt : 0;
        this.emit({ type: 'activity.completed', activity });
        return activity;
    }
    fail(activityId, error) {
        const activity = this.activities.get(activityId);
        if (!activity || isTerminalActivityStatus(activity.status))
            return null;
        activity.status = 'failed';
        activity.error = error;
        activity.completedAt = Date.now();
        activity.durationMs = activity.startedAt ? activity.completedAt - activity.startedAt : 0;
        this.emit({ type: 'activity.failed', activity });
        return activity;
    }
    cancel(activityId) {
        const activity = this.activities.get(activityId);
        if (!activity || isTerminalActivityStatus(activity.status))
            return null;
        activity.status = 'cancelled';
        activity.completedAt = Date.now();
        activity.durationMs = activity.startedAt ? activity.completedAt - activity.startedAt : 0;
        this.emit({ type: 'activity.cancelled', activity });
        return activity;
    }
    get(activityId) {
        return this.activities.get(activityId);
    }
    getByToolCallId(toolCallId) {
        for (const activity of this.activities.values()) {
            if (activity.toolCallId === toolCallId)
                return activity;
        }
        return undefined;
    }
    list(filter) {
        let results = Array.from(this.activities.values());
        if (filter?.status) {
            results = results.filter((a) => a.status === filter.status);
        }
        if (filter?.type) {
            results = results.filter((a) => a.type === filter.type);
        }
        return results.sort((a, b) => a.createdAt - b.createdAt);
    }
    getBlockedActivities() {
        return this.list().filter((activity) => {
            if (activity.status !== 'pending')
                return false;
            return activity.blockedBy.some((depId) => {
                const dep = this.activities.get(depId);
                return dep && !isTerminalActivityStatus(dep.status);
            });
        });
    }
    getReadyActivities() {
        return this.list().filter((activity) => {
            if (activity.status !== 'pending')
                return false;
            return activity.blockedBy.every((depId) => {
                const dep = this.activities.get(depId);
                return !dep || isTerminalActivityStatus(dep.status);
            });
        });
    }
    stats() {
        const all = this.list();
        return {
            total: all.length,
            pending: all.filter((a) => a.status === 'pending').length,
            running: all.filter((a) => a.status === 'running').length,
            completed: all.filter((a) => a.status === 'completed').length,
            failed: all.filter((a) => a.status === 'failed').length,
            cancelled: all.filter((a) => a.status === 'cancelled').length,
        };
    }
    clear() {
        this.activities.clear();
    }
}
//# sourceMappingURL=memory.js.map