"use strict";
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.workflowEngine = exports.WorkflowEngine = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const events_1 = require("events");
class WorkflowEngine extends events_1.EventEmitter {
    workflowsDir;
    activeWorkflows;
    constructor() {
        super();
        this.workflowsDir = path.join(process.cwd(), '.opencode', 'workflows', 'state');
        this.activeWorkflows = new Map();
        this.ensureDirectories();
    }
    ensureDirectories() {
        if (!fs.existsSync(this.workflowsDir)) {
            fs.mkdirSync(this.workflowsDir, { recursive: true });
        }
    }
    /**
     * Create a new workflow
     */
    createWorkflow(_name, definition, context = {}) {
        const workflow = {
            id: this.generateId(),
            name: definition.name,
            description: definition.description,
            steps: definition.steps.map((step, index) => ({
                id: `step-${index + 1}`,
                agent: step.agent,
                task: step.task,
                dependsOn: step.dependsOn,
                status: 'pending'
            })),
            context,
            status: 'pending',
            createdAt: new Date(),
            updatedAt: new Date()
        };
        this.activeWorkflows.set(workflow.id, workflow);
        this.saveWorkflow(workflow);
        this.emit('workflow:created', workflow);
        return workflow;
    }
    /**
     * Execute a workflow
     */
    async executeWorkflow(workflowId) {
        const workflow = this.activeWorkflows.get(workflowId);
        if (!workflow) {
            throw new Error(`Workflow ${workflowId} not found`);
        }
        workflow.status = 'running';
        workflow.updatedAt = new Date();
        this.saveWorkflow(workflow);
        this.emit('workflow:started', workflow);
        try {
            for (const step of workflow.steps) {
                if (step.status === 'pending') {
                    await this.executeStep(workflow, step);
                }
            }
            workflow.status = 'completed';
            workflow.updatedAt = new Date();
            this.saveWorkflow(workflow);
            this.emit('workflow:completed', workflow);
        }
        catch (error) {
            workflow.status = 'failed';
            workflow.updatedAt = new Date();
            this.saveWorkflow(workflow);
            this.emit('workflow:failed', workflow, error);
            throw error;
        }
        return workflow;
    }
    /**
     * Execute a single step
     */
    async executeStep(workflow, step) {
        // Check dependencies
        if (step.dependsOn && step.dependsOn.length > 0) {
            const depsCompleted = step.dependsOn.every(depId => {
                const dep = workflow.steps.find(s => s.id === depId);
                return dep?.status === 'completed';
            });
            if (!depsCompleted) {
                step.status = 'skipped';
                step.error = 'Dependencies not completed';
                this.saveWorkflow(workflow);
                return;
            }
        }
        step.status = 'running';
        step.startedAt = new Date();
        workflow.updatedAt = new Date();
        this.saveWorkflow(workflow);
        this.emit('step:started', workflow, step);
        try {
            // Simulate agent execution (in real implementation, this would call the agent)
            const result = await this.executeAgent(step.agent, step.task, workflow.context);
            step.status = 'completed';
            step.output = result;
            step.completedAt = new Date();
            workflow.updatedAt = new Date();
            this.saveWorkflow(workflow);
            this.emit('step:completed', workflow, step);
        }
        catch (error) {
            step.status = 'failed';
            step.error = error instanceof Error ? error.message : String(error);
            step.completedAt = new Date();
            workflow.updatedAt = new Date();
            this.saveWorkflow(workflow);
            this.emit('step:failed', workflow, step, error);
            throw error;
        }
    }
    /**
     * Execute agent (placeholder for actual implementation)
     */
    async executeAgent(agent, task, _context) {
        // This would be replaced with actual agent invocation
        return `Agent ${agent} completed task: ${task}`;
    }
    /**
     * Save workflow state
     */
    saveWorkflow(workflow) {
        const workflowPath = path.join(this.workflowsDir, `${workflow.id}.json`);
        fs.writeFileSync(workflowPath, JSON.stringify(workflow, null, 2));
    }
    /**
     * Load workflow
     */
    loadWorkflow(workflowId) {
        const workflowPath = path.join(this.workflowsDir, `${workflowId}.json`);
        if (fs.existsSync(workflowPath)) {
            const data = fs.readFileSync(workflowPath, 'utf-8');
            return JSON.parse(data);
        }
        return null;
    }
    /**
     * Get workflow status
     */
    getWorkflowStatus(workflowId) {
        const workflow = this.loadWorkflow(workflowId);
        if (!workflow)
            return null;
        const completed = workflow.steps.filter(s => s.status === 'completed').length;
        return {
            status: workflow.status,
            progress: { completed, total: workflow.steps.length },
            steps: workflow.steps
        };
    }
    /**
     * Resume a failed workflow
     */
    async resumeWorkflow(workflowId) {
        const workflow = this.loadWorkflow(workflowId);
        if (!workflow) {
            throw new Error(`Workflow ${workflowId} not found`);
        }
        // Reset failed steps to pending
        workflow.steps.forEach(step => {
            if (step.status === 'failed') {
                step.status = 'pending';
                step.error = undefined;
                step.output = undefined;
            }
        });
        workflow.status = 'running';
        workflow.updatedAt = new Date();
        this.activeWorkflows.set(workflow.id, workflow);
        this.saveWorkflow(workflow);
        return this.executeWorkflow(workflowId);
    }
    /**
     * Cancel a running workflow
     */
    cancelWorkflow(workflowId) {
        const workflow = this.loadWorkflow(workflowId);
        if (!workflow)
            return false;
        if (workflow.status === 'running') {
            workflow.status = 'failed';
            workflow.updatedAt = new Date();
            this.saveWorkflow(workflow);
            this.emit('workflow:cancelled', workflow);
            return true;
        }
        return false;
    }
    /**
     * List all workflows
     */
    listWorkflows() {
        const workflows = [];
        if (fs.existsSync(this.workflowsDir)) {
            const files = fs.readdirSync(this.workflowsDir);
            for (const file of files) {
                if (file.endsWith('.json')) {
                    const data = fs.readFileSync(path.join(this.workflowsDir, file), 'utf-8');
                    const workflow = JSON.parse(data);
                    workflows.push({
                        id: workflow.id,
                        name: workflow.name,
                        status: workflow.status,
                        createdAt: workflow.createdAt,
                        updatedAt: workflow.updatedAt
                    });
                }
            }
        }
        return workflows.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
    }
    /**
     * Get predefined workflow definitions
     */
    getPredefinedWorkflows() {
        return {
            'landing-page': {
                name: 'Landing Page',
                description: 'Build a complete landing page with design and implementation',
                steps: [
                    {
                        agent: '@design-system-consultant',
                        task: 'Design color palette, typography, and component specs'
                    },
                    {
                        agent: '@frontend-developer',
                        task: 'Build landing page components with design specs',
                        dependsOn: ['step-1']
                    }
                ]
            },
            'saas-mvp': {
                name: 'SaaS MVP',
                description: 'Build a complete SaaS MVP from scratch',
                steps: [
                    {
                        agent: '@product-manager',
                        task: 'Define MVP scope and user stories'
                    },
                    {
                        agent: '@api-architect',
                        task: 'Design API endpoints and data models',
                        dependsOn: ['step-1']
                    },
                    {
                        agent: '@backend-architect',
                        task: 'Implement database schema and API endpoints',
                        dependsOn: ['step-2']
                    },
                    {
                        agent: '@frontend-developer',
                        task: 'Build frontend UI and integrate with API',
                        dependsOn: ['step-3']
                    },
                    {
                        agent: '@testing-reality-checker',
                        task: 'Test the complete MVP and validate functionality',
                        dependsOn: ['step-4']
                    }
                ]
            },
            'api-service': {
                name: 'API Service',
                description: 'Create a complete API service',
                steps: [
                    {
                        agent: '@api-architect',
                        task: 'Design REST/GraphQL API specification'
                    },
                    {
                        agent: '@backend-architect',
                        task: 'Implement API endpoints and business logic',
                        dependsOn: ['step-1']
                    },
                    {
                        agent: '@testing-api-tester',
                        task: 'Test all API endpoints',
                        dependsOn: ['step-2']
                    }
                ]
            },
            'fullstack-app': {
                name: 'Full-Stack Application',
                description: 'Build a complete full-stack application',
                steps: [
                    {
                        agent: '@fullstack-developer',
                        task: 'Scaffold full-stack project with chosen framework'
                    },
                    {
                        agent: '@design-system-consultant',
                        task: 'Design UI system and component library',
                        dependsOn: ['step-1']
                    },
                    {
                        agent: '@fullstack-developer',
                        task: 'Implement frontend and backend integration',
                        dependsOn: ['step-2']
                    },
                    {
                        agent: '@testing-reality-checker',
                        task: 'End-to-end testing and validation',
                        dependsOn: ['step-3']
                    }
                ]
            },
            'auth-system': {
                name: 'Authentication System',
                description: 'Implement complete authentication',
                steps: [
                    {
                        agent: '@security-engineer',
                        task: 'Design authentication flow and security model'
                    },
                    {
                        agent: '@fullstack-developer',
                        task: 'Implement authentication UI and API',
                        dependsOn: ['step-1']
                    },
                    {
                        agent: '@security-engineer',
                        task: 'Security review and penetration testing',
                        dependsOn: ['step-2']
                    }
                ]
            }
        };
    }
    /**
     * Run a predefined workflow
     */
    async runPredefinedWorkflow(workflowName, context = {}) {
        const workflows = this.getPredefinedWorkflows();
        const definition = workflows[workflowName];
        if (!definition) {
            throw new Error(`Workflow "${workflowName}" not found`);
        }
        const workflow = this.createWorkflow(workflowName, definition, context);
        return this.executeWorkflow(workflow.id);
    }
    /**
     * Generate unique ID
     */
    generateId() {
        return `wf-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
    }
}
exports.WorkflowEngine = WorkflowEngine;
// Export singleton
exports.workflowEngine = new WorkflowEngine();
//# sourceMappingURL=workflow-engine.js.map