"use strict";
/**
 * Background Executor
 * Handles async workflow execution with status tracking
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.BackgroundExecutor = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
class BackgroundExecutor {
    worktree;
    workflowsDir;
    executor;
    constructor(worktree, executor) {
        this.worktree = worktree;
        this.workflowsDir = path.join(worktree, '.cli-brain', 'workflows');
        this.executor = executor;
        // Ensure directory exists
        fs.mkdirSync(this.workflowsDir, { recursive: true });
    }
    /**
     * Generate unique workflow ID
     */
    generateId() {
        return `WF-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
    }
    /**
     * Save workflow state
     */
    saveWorkflow(workflow) {
        const workflowPath = path.join(this.workflowsDir, `${workflow.id}.json`);
        fs.writeFileSync(workflowPath, JSON.stringify(workflow, null, 2));
    }
    /**
     * Load workflow state
     */
    loadWorkflow(id) {
        const workflowPath = path.join(this.workflowsDir, `${id}.json`);
        if (!fs.existsSync(workflowPath)) {
            return null;
        }
        try {
            const data = fs.readFileSync(workflowPath, 'utf-8');
            return JSON.parse(data);
        }
        catch {
            return null;
        }
    }
    /**
     * Start single agent execution in background
     */
    async start(config) {
        const id = this.generateId();
        const workflow = {
            id,
            name: config.agent,
            description: `Execute ${config.agent}`,
            status: 'pending',
            steps: [{
                    id: 'step-1',
                    agent: config.agent,
                    task: config.task,
                    status: 'pending',
                    model: config.model
                }],
            context: {},
            startTime: new Date().toISOString(),
            currentStepIndex: 0
        };
        this.saveWorkflow(workflow);
        // Start async execution
        this.executeAsync(id, config);
        return id;
    }
    /**
     * Execute asynchronously
     */
    async executeAsync(id, config) {
        const workflow = this.loadWorkflow(id);
        if (!workflow)
            return;
        // Update status to running
        workflow.status = 'running';
        workflow.steps[0].status = 'running';
        workflow.steps[0].startTime = new Date().toISOString();
        this.saveWorkflow(workflow);
        try {
            // Execute agent
            const result = await this.executor.execute({
                agent: config.agent,
                task: config.task,
                model: config.model
            });
            // Update workflow
            const updated = this.loadWorkflow(id);
            if (updated) {
                updated.steps[0].status = result.success ? 'completed' : 'failed';
                updated.steps[0].output = result.success ? result.content : undefined;
                updated.steps[0].error = result.error;
                updated.steps[0].endTime = new Date().toISOString();
                updated.status = result.success ? 'completed' : 'failed';
                updated.endTime = new Date().toISOString();
                this.saveWorkflow(updated);
            }
        }
        catch (error) {
            const updated = this.loadWorkflow(id);
            if (updated) {
                updated.steps[0].status = 'failed';
                updated.steps[0].error = error instanceof Error ? error.message : String(error);
                updated.steps[0].endTime = new Date().toISOString();
                updated.status = 'failed';
                updated.endTime = new Date().toISOString();
                this.saveWorkflow(updated);
            }
        }
    }
    /**
     * Start multi-step workflow
     */
    async startWorkflow(workflowName, steps, context = {}) {
        const id = this.generateId();
        const workflow = {
            id,
            name: workflowName,
            description: `Workflow: ${workflowName}`,
            status: 'pending',
            steps: steps.map((step, index) => ({
                id: `step-${index + 1}`,
                agent: step.agent,
                task: step.task,
                status: 'pending',
                model: step.model
            })),
            context,
            startTime: new Date().toISOString(),
            currentStepIndex: 0
        };
        this.saveWorkflow(workflow);
        // Start async workflow execution
        this.executeWorkflowAsync(id);
        return id;
    }
    /**
     * Execute workflow asynchronously
     */
    async executeWorkflowAsync(id) {
        let workflow = this.loadWorkflow(id);
        if (!workflow)
            return;
        workflow.status = 'running';
        this.saveWorkflow(workflow);
        try {
            for (let i = 0; i < workflow.steps.length; i++) {
                workflow = this.loadWorkflow(id);
                workflow.currentStepIndex = i;
                const step = workflow.steps[i];
                step.status = 'running';
                step.startTime = new Date().toISOString();
                this.saveWorkflow(workflow);
                try {
                    const result = await this.executor.execute({
                        agent: step.agent,
                        task: step.task,
                        model: step.model
                    });
                    step.status = result.success ? 'completed' : 'failed';
                    step.output = result.success ? result.content : undefined;
                    step.error = result.error;
                    step.endTime = new Date().toISOString();
                    // Pass output to next step's context
                    if (result.success && i < workflow.steps.length - 1) {
                        workflow.context[`${step.agent}-output`] = result.content;
                    }
                }
                catch (error) {
                    step.status = 'failed';
                    step.error = error instanceof Error ? error.message : String(error);
                    step.endTime = new Date().toISOString();
                    workflow.status = 'failed';
                    workflow.endTime = new Date().toISOString();
                    this.saveWorkflow(workflow);
                    return;
                }
                this.saveWorkflow(workflow);
            }
            // All steps completed
            workflow = this.loadWorkflow(id);
            workflow.status = 'completed';
            workflow.endTime = new Date().toISOString();
            this.saveWorkflow(workflow);
        }
        catch (error) {
            workflow = this.loadWorkflow(id);
            workflow.status = 'failed';
            workflow.endTime = new Date().toISOString();
            this.saveWorkflow(workflow);
        }
    }
    /**
     * Get workflow status
     */
    getStatus(id) {
        const workflow = this.loadWorkflow(id);
        if (!workflow)
            return null;
        const now = new Date();
        const start = new Date(workflow.startTime);
        const elapsed = workflow.endTime
            ? new Date(workflow.endTime).getTime() - start.getTime()
            : now.getTime() - start.getTime();
        const current = workflow.steps.filter(s => s.status === 'completed').length;
        const total = workflow.steps.length;
        return {
            id: workflow.id,
            name: workflow.name,
            status: workflow.status,
            progress: {
                current,
                total,
                percent: Math.round((current / total) * 100)
            },
            steps: workflow.steps.map(s => ({
                id: s.id,
                agent: s.agent,
                status: s.status,
                duration: s.endTime && s.startTime
                    ? new Date(s.endTime).getTime() - new Date(s.startTime).getTime()
                    : s.startTime
                        ? now.getTime() - new Date(s.startTime).getTime()
                        : undefined
            })),
            startedAt: workflow.startTime,
            elapsed
        };
    }
    /**
     * List all workflows
     */
    listWorkflows() {
        const workflows = [];
        if (!fs.existsSync(this.workflowsDir)) {
            return workflows;
        }
        const files = fs.readdirSync(this.workflowsDir).filter(f => f.endsWith('.json'));
        for (const file of files) {
            try {
                const data = JSON.parse(fs.readFileSync(path.join(this.workflowsDir, file), 'utf-8'));
                workflows.push({
                    id: data.id,
                    name: data.name,
                    status: data.status,
                    startedAt: data.startTime
                });
            }
            catch {
                // Skip invalid files
            }
        }
        return workflows.sort((a, b) => new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime());
    }
    /**
     * Cancel running workflow
     */
    cancel(id) {
        const workflow = this.loadWorkflow(id);
        if (!workflow || workflow.status !== 'running') {
            return false;
        }
        workflow.status = 'failed';
        workflow.endTime = new Date().toISOString();
        // Mark current step as failed
        const currentStep = workflow.steps[workflow.currentStepIndex];
        if (currentStep && currentStep.status === 'running') {
            currentStep.status = 'failed';
            currentStep.error = 'Cancelled by user';
            currentStep.endTime = new Date().toISOString();
        }
        this.saveWorkflow(workflow);
        return true;
    }
    /**
     * Get workflow output
     */
    getOutput(id) {
        const workflow = this.loadWorkflow(id);
        if (!workflow)
            return null;
        if (workflow.status === 'completed') {
            // Get last step's output
            const lastStep = workflow.steps[workflow.steps.length - 1];
            return { success: true, output: lastStep.output };
        }
        else if (workflow.status === 'failed') {
            const failedStep = workflow.steps.find(s => s.status === 'failed');
            return { success: false, error: failedStep?.error || 'Workflow failed' };
        }
        return null;
    }
}
exports.BackgroundExecutor = BackgroundExecutor;
//# sourceMappingURL=background-executor.js.map