"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WorkflowController = void 0;
const stateMachine_1 = require("../../workflow/stateMachine");
const webhookService_1 = require("../../workflow/webhookService");
const auditLogger_1 = require("../../workflow/auditLogger");
const jobQueue_1 = require("../../workflow/jobQueue");
const gitEventHandler_1 = require("../../workflow/gitEventHandler");
/**
 * Workflow Controller
 * Handles all workflow-related HTTP requests
 */
class WorkflowController {
    /**
     * State Machine Endpoints
     */
    async getTaskState(req, res) {
        try {
            const { taskId } = req.params;
            const state = await stateMachine_1.stateMachineService.getCurrentState(taskId);
            res.json({
                success: true,
                data: {
                    taskId,
                    currentState: state.value,
                    context: state.context,
                    history: state.history
                }
            });
        }
        catch (error) {
            res.status(500).json({
                success: false,
                error: error.message
            });
        }
    }
    async getAvailableTransitions(req, res) {
        try {
            const { taskId } = req.params;
            const transitions = await stateMachine_1.stateMachineService.getAvailableTransitions(taskId);
            res.json({
                success: true,
                data: {
                    taskId,
                    availableTransitions: transitions
                }
            });
        }
        catch (error) {
            res.status(500).json({
                success: false,
                error: error.message
            });
        }
    }
    async executeTransition(req, res) {
        try {
            const { taskId, event, metadata, userId, reason } = req.body;
            const newState = await stateMachine_1.stateMachineService.transition(taskId, {
                type: event,
                ...metadata,
                userId,
                reason
            });
            // Log the transition
            await auditLogger_1.auditLogger.logWorkflowTransition(taskId, String(newState.history?.value || 'unknown'), String(newState.value), event, { userId, reason, ...metadata });
            res.json({
                success: true,
                data: {
                    taskId,
                    previousState: newState.history?.value,
                    currentState: newState.value,
                    context: newState.context
                }
            });
        }
        catch (error) {
            res.status(400).json({
                success: false,
                error: error.message
            });
        }
    }
    async validateTransition(req, res) {
        try {
            const { taskId, event } = req.body;
            const isValid = await stateMachine_1.stateMachineService.canTransition(taskId, { type: event });
            res.json({
                success: true,
                data: {
                    taskId,
                    event,
                    isValid
                }
            });
        }
        catch (error) {
            res.status(500).json({
                success: false,
                error: error.message
            });
        }
    }
    /**
     * Webhook Endpoints
     */
    async getWebhooks(req, res) {
        try {
            const { active, event } = req.query;
            const filter = {};
            if (active !== undefined) {
                filter.active = active === 'true';
            }
            if (event) {
                filter.event = String(event);
            }
            const webhooks = await webhookService_1.webhookService.getWebhooks(filter);
            res.json({
                success: true,
                data: webhooks
            });
        }
        catch (error) {
            res.status(500).json({
                success: false,
                error: error.message
            });
        }
    }
    async registerWebhook(req, res) {
        try {
            const webhook = await webhookService_1.webhookService.registerWebhook(req.body);
            res.status(201).json({
                success: true,
                data: webhook
            });
        }
        catch (error) {
            res.status(400).json({
                success: false,
                error: error.message
            });
        }
    }
    async updateWebhook(req, res) {
        try {
            const { id } = req.params;
            const webhook = await webhookService_1.webhookService.updateWebhook(id, req.body);
            res.json({
                success: true,
                data: webhook
            });
        }
        catch (error) {
            res.status(400).json({
                success: false,
                error: error.message
            });
        }
    }
    async deleteWebhook(req, res) {
        try {
            const { id } = req.params;
            await webhookService_1.webhookService.deleteWebhook(id);
            res.json({
                success: true,
                message: 'Webhook deleted successfully'
            });
        }
        catch (error) {
            res.status(400).json({
                success: false,
                error: error.message
            });
        }
    }
    async testWebhook(req, res) {
        try {
            const { id } = req.params;
            const result = await webhookService_1.webhookService.testWebhook(id);
            res.json({
                success: true,
                data: result
            });
        }
        catch (error) {
            res.status(400).json({
                success: false,
                error: error.message
            });
        }
    }
    async getWebhookDeliveries(req, res) {
        try {
            const { id } = req.params;
            const { limit } = req.query;
            const deliveries = await webhookService_1.webhookService.getDeliveryHistory(id, limit ? parseInt(String(limit)) : 100);
            res.json({
                success: true,
                data: deliveries
            });
        }
        catch (error) {
            res.status(500).json({
                success: false,
                error: error.message
            });
        }
    }
    /**
     * Audit Log Endpoints
     */
    async queryAuditLogs(req, res) {
        try {
            const query = req.query;
            const options = {};
            // Parse query parameters
            if (query.entityType)
                options.entityType = String(query.entityType);
            if (query.entityId)
                options.entityId = String(query.entityId);
            if (query.actorId)
                options.actorId = String(query.actorId);
            if (query.action)
                options.action = String(query.action);
            if (query.severity)
                options.severity = String(query.severity);
            if (query.startDate)
                options.startDate = new Date(String(query.startDate));
            if (query.endDate)
                options.endDate = new Date(String(query.endDate));
            if (query.tags)
                options.tags = Array.isArray(query.tags) ? query.tags : [query.tags];
            if (query.limit)
                options.limit = parseInt(String(query.limit));
            if (query.offset)
                options.offset = parseInt(String(query.offset));
            if (query.sort)
                options.sort = String(query.sort);
            const logs = await auditLogger_1.auditLogger.query(options);
            res.json({
                success: true,
                data: logs
            });
        }
        catch (error) {
            res.status(500).json({
                success: false,
                error: error.message
            });
        }
    }
    async getAuditStatistics(req, res) {
        try {
            const { startDate, endDate } = req.query;
            const statistics = await auditLogger_1.auditLogger.getStatistics(startDate ? new Date(String(startDate)) : undefined, endDate ? new Date(String(endDate)) : undefined);
            res.json({
                success: true,
                data: statistics
            });
        }
        catch (error) {
            res.status(500).json({
                success: false,
                error: error.message
            });
        }
    }
    async getAuditTimeline(req, res) {
        try {
            const { entityId } = req.params;
            const { entityType } = req.query;
            const timeline = await auditLogger_1.auditLogger.getTimeline(entityId, entityType ? String(entityType) : undefined);
            res.json({
                success: true,
                data: timeline
            });
        }
        catch (error) {
            res.status(500).json({
                success: false,
                error: error.message
            });
        }
    }
    async exportAuditLogs(req, res) {
        try {
            const { format, ...queryOptions } = req.query;
            const exportData = await auditLogger_1.auditLogger.exportLogs(queryOptions, format);
            // Set appropriate headers
            const contentType = format === 'csv'
                ? 'text/csv'
                : 'application/json';
            const filename = `audit-logs-${Date.now()}.${format || 'json'}`;
            res.setHeader('Content-Type', contentType);
            res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
            res.send(exportData);
        }
        catch (error) {
            res.status(500).json({
                success: false,
                error: error.message
            });
        }
    }
    /**
     * Job Queue Endpoints
     */
    async addJob(req, res) {
        try {
            const { queue, type, taskId, payload, metadata, priority } = req.body;
            const job = await jobQueue_1.jobQueueService.addJob(queue || 'workflow', {
                type: type,
                taskId,
                payload,
                metadata
            }, { priority });
            res.status(201).json({
                success: true,
                data: {
                    jobId: job.id,
                    queue: queue || 'workflow',
                    status: await job.getState()
                }
            });
        }
        catch (error) {
            res.status(400).json({
                success: false,
                error: error.message
            });
        }
    }
    async scheduleJob(req, res) {
        try {
            const { queue, type, taskId, payload, metadata, delay, scheduleAt } = req.body;
            const delayMs = scheduleAt
                ? new Date(scheduleAt).getTime() - Date.now()
                : delay;
            const job = await jobQueue_1.jobQueueService.scheduleJob(queue || 'scheduled', {
                type: type,
                taskId,
                payload,
                metadata
            }, delayMs);
            res.status(201).json({
                success: true,
                data: {
                    jobId: job.id,
                    queue: queue || 'scheduled',
                    scheduledFor: new Date(Date.now() + delayMs).toISOString()
                }
            });
        }
        catch (error) {
            res.status(400).json({
                success: false,
                error: error.message
            });
        }
    }
    async addRecurringJob(req, res) {
        try {
            const { queue, type, taskId, payload, metadata, cron } = req.body;
            const job = await jobQueue_1.jobQueueService.addRecurringJob(queue || 'scheduled', {
                type: type,
                taskId,
                payload,
                metadata
            }, cron);
            res.status(201).json({
                success: true,
                data: {
                    jobId: job.id,
                    queue: queue || 'scheduled',
                    cronExpression: cron
                }
            });
        }
        catch (error) {
            res.status(400).json({
                success: false,
                error: error.message
            });
        }
    }
    async getQueueStatistics(req, res) {
        try {
            const { name } = req.params;
            const statistics = await jobQueue_1.jobQueueService.getQueueStatistics(name);
            res.json({
                success: true,
                data: statistics
            });
        }
        catch (error) {
            res.status(400).json({
                success: false,
                error: error.message
            });
        }
    }
    async pauseQueue(req, res) {
        try {
            const { name } = req.params;
            await jobQueue_1.jobQueueService.pauseQueue(name);
            res.json({
                success: true,
                message: `Queue ${name} paused successfully`
            });
        }
        catch (error) {
            res.status(400).json({
                success: false,
                error: error.message
            });
        }
    }
    async resumeQueue(req, res) {
        try {
            const { name } = req.params;
            await jobQueue_1.jobQueueService.resumeQueue(name);
            res.json({
                success: true,
                message: `Queue ${name} resumed successfully`
            });
        }
        catch (error) {
            res.status(400).json({
                success: false,
                error: error.message
            });
        }
    }
    async clearQueue(req, res) {
        try {
            const { name } = req.params;
            await jobQueue_1.jobQueueService.clearQueue(name);
            res.json({
                success: true,
                message: `Queue ${name} cleared successfully`
            });
        }
        catch (error) {
            res.status(400).json({
                success: false,
                error: error.message
            });
        }
    }
    /**
     * Git Integration Endpoints
     */
    async createTaskBranch(req, res) {
        try {
            const { taskId, taskTitle } = req.body;
            const branchName = await gitEventHandler_1.gitEventHandler.createTaskBranch(taskId, taskTitle);
            res.status(201).json({
                success: true,
                data: {
                    taskId,
                    branchName
                }
            });
        }
        catch (error) {
            res.status(400).json({
                success: false,
                error: error.message
            });
        }
    }
    async getTaskGitInfo(req, res) {
        try {
            const { taskId } = req.params;
            const gitInfo = await gitEventHandler_1.gitEventHandler.getTaskGitInfo(taskId);
            if (!gitInfo) {
                res.status(404).json({
                    success: false,
                    error: 'No Git information found for this task'
                });
                return;
            }
            res.json({
                success: true,
                data: gitInfo
            });
        }
        catch (error) {
            res.status(500).json({
                success: false,
                error: error.message
            });
        }
    }
    async handleGitWebhook(req, res) {
        try {
            // Verify webhook signature if configured
            const signature = req.headers['x-hub-signature-256'];
            // TODO: Implement signature verification
            const event = req.headers['x-github-event'];
            switch (event) {
                case 'pull_request':
                    await gitEventHandler_1.gitEventHandler.handlePullRequestEvent(req.body);
                    break;
                // Add more event handlers as needed
            }
            res.json({
                success: true,
                message: 'Webhook processed successfully'
            });
        }
        catch (error) {
            res.status(500).json({
                success: false,
                error: error.message
            });
        }
    }
}
exports.WorkflowController = WorkflowController;
//# sourceMappingURL=workflow.controller.js.map