/**
 * State Manager - Workflow state tracking and checkpointing
 *
 * Manages workflow state, checkpoints, and recovery for autonomous execution.
 *
 * Part of increment 0039: Ultra-Smart Next Command
 *
 * @module core/workflow/state-manager
 * @since v0.22.0
 */
import * as fs from '../../utils/fs-native.js';
import * as path from 'path';
/**
 * State Manager - Track workflow state and checkpoints
 */
export class StateManager {
    constructor(checkpointDir, maxCheckpoints = 10) {
        this.checkpointDir = checkpointDir || '.specweave/checkpoints';
        this.maxCheckpoints = maxCheckpoints;
    }
    /**
     * Save checkpoint
     *
     * @param checkpoint - Checkpoint data
     */
    async saveCheckpoint(checkpoint) {
        await fs.ensureDir(this.checkpointDir);
        const checkpointPath = path.join(this.checkpointDir, `${checkpoint.incrementId}-${checkpoint.id}.json`);
        await fs.writeJson(checkpointPath, checkpoint, { spaces: 2 });
        // Cleanup old checkpoints
        await this.cleanupOldCheckpoints(checkpoint.incrementId);
    }
    /**
     * Load checkpoints for increment (sorted by timestamp, newest first)
     */
    async loadCheckpoints(incrementId) {
        if (!await fs.pathExists(this.checkpointDir)) {
            return [];
        }
        const files = await fs.readdir(this.checkpointDir);
        const checkpointFiles = files.filter(f => f.startsWith(`${incrementId}-`) && f.endsWith('.json'));
        const checkpoints = [];
        for (const file of checkpointFiles) {
            try {
                const checkpoint = await fs.readJson(path.join(this.checkpointDir, file));
                checkpoints.push(checkpoint);
            }
            catch {
                console.warn(`Failed to load checkpoint ${file}`);
            }
        }
        return checkpoints.sort((a, b) => b.timestamp - a.timestamp);
    }
    /**
     * Get latest checkpoint for increment
     */
    async getLatestCheckpoint(incrementId) {
        const checkpoints = await this.loadCheckpoints(incrementId);
        return checkpoints[0] ?? null;
    }
    /**
     * Delete checkpoint
     *
     * @param incrementId - Increment ID
     * @param checkpointId - Checkpoint ID
     */
    async deleteCheckpoint(incrementId, checkpointId) {
        const checkpointPath = path.join(this.checkpointDir, `${incrementId}-${checkpointId}.json`);
        if (await fs.pathExists(checkpointPath)) {
            await fs.remove(checkpointPath);
        }
    }
    /**
     * Cleanup old checkpoints (keep only N most recent)
     *
     * @param incrementId - Increment ID
     */
    async cleanupOldCheckpoints(incrementId) {
        const checkpoints = await this.loadCheckpoints(incrementId);
        if (checkpoints.length > this.maxCheckpoints) {
            const toDelete = checkpoints.slice(this.maxCheckpoints);
            for (const checkpoint of toDelete) {
                await this.deleteCheckpoint(incrementId, checkpoint.id);
            }
        }
    }
    /**
     * Detect infinite loop (same phase repeated threshold times consecutively)
     */
    detectLoop(phaseHistory, threshold = 3) {
        if (phaseHistory.length < threshold)
            return false;
        const recentPhases = phaseHistory.slice(-threshold);
        return new Set(recentPhases).size === 1;
    }
    /**
     * Record state transition
     *
     * (For now, this is a no-op - will be used for analytics/debugging)
     *
     * @param transition - State transition record
     */
    recordTransition(transition) {
        // TODO: Implement transition logging
        // For now, just log to console
        console.log(`State transition: ${transition.from} → ${transition.to} (${transition.action})`);
    }
}
//# sourceMappingURL=state-manager.js.map