/**
 * Request adapters for normalizing input from different sources
 *
 * Each adapter transforms source-specific input into a unified WorkflowRequest.
 */
import * as fs from 'fs';
import * as path from 'path';
import { randomUUID } from 'crypto';
/**
 * Base adapter with shared validation logic
 */
class BaseRequestAdapter {
    validate(request) {
        const errors = [];
        // Validate workflowId
        if (!request.workflowId || typeof request.workflowId !== 'string') {
            errors.push({
                path: 'workflowId',
                message: 'Workflow ID is required and must be a string',
                expected: 'string',
                actual: typeof request.workflowId,
            });
        }
        // Validate params is an object
        if (request.params !== null && typeof request.params !== 'object') {
            errors.push({
                path: 'params',
                message: 'Params must be an object',
                expected: 'object',
                actual: typeof request.params,
            });
        }
        // Validate context
        if (!request.context) {
            errors.push({
                path: 'context',
                message: 'Execution context is required',
            });
        }
        else {
            if (!request.context.requestId) {
                errors.push({
                    path: 'context.requestId',
                    message: 'Request ID is required',
                });
            }
        }
        return {
            valid: errors.length === 0,
            errors: errors.length > 0 ? errors : undefined,
        };
    }
    /**
     * Create a default execution context
     */
    createContext(source, options = {}) {
        return {
            source,
            environment: options.environment ?? this.detectEnvironment(),
            requestId: options.requestId ?? randomUUID(),
            includeTrace: options.includeTrace ?? true,
            timeout: options.timeout,
        };
    }
    /**
     * Detect runtime environment
     */
    detectEnvironment() {
        const nodeEnv = process.env.NODE_ENV?.toLowerCase();
        if (nodeEnv === 'production' || nodeEnv === 'prod') {
            return 'production';
        }
        if (nodeEnv === 'staging' || nodeEnv === 'stage') {
            return 'staging';
        }
        return 'development';
    }
}
/**
 * CLI request adapter
 *
 * Parses CLI command input into a WorkflowRequest
 */
export class CliRequestAdapter extends BaseRequestAdapter {
    parseRequest(input) {
        // Parse params from JSON string or file
        let params = {};
        if (input.params) {
            try {
                params = JSON.parse(input.params);
            }
            catch {
                throw new Error(`Invalid JSON in params: ${input.params}`);
            }
        }
        else if (input.paramsFile) {
            const paramsFilePath = path.resolve(input.paramsFile);
            if (!fs.existsSync(paramsFilePath)) {
                throw new Error(`Params file not found: ${paramsFilePath}`);
            }
            try {
                const content = fs.readFileSync(paramsFilePath, 'utf8');
                params = JSON.parse(content);
            }
            catch {
                throw new Error(`Failed to parse params file: ${input.paramsFile}`);
            }
        }
        // Determine trace inclusion
        const includeTrace = input.trace ?? !input.production;
        return {
            workflowId: input.workflowName || this.extractWorkflowId(input.filePath),
            params,
            context: this.createContext('cli', {
                includeTrace,
                timeout: input.timeout,
                environment: input.production ? 'production' : 'development',
            }),
        };
    }
    /**
     * Extract workflow ID from file path (uses filename without extension)
     */
    extractWorkflowId(filePath) {
        const basename = path.basename(filePath, path.extname(filePath));
        return basename;
    }
}
/**
 * HTTP request adapter (for Fastify/Express-like servers)
 *
 * Parses HTTP request into a WorkflowRequest
 */
export class HttpRequestAdapter extends BaseRequestAdapter {
    parseRequest(input) {
        const workflowId = input.params.name || input.params.workflow || '';
        const includeTrace = input.query.trace === 'true';
        return {
            workflowId,
            params: input.body || {},
            context: this.createContext('http', {
                requestId: input.headers['x-request-id'],
                includeTrace,
            }),
        };
    }
}
export function createAdapter(source) {
    switch (source) {
        case 'cli':
            return new CliRequestAdapter();
        case 'http':
            return new HttpRequestAdapter();
    }
}
//# sourceMappingURL=adapters.js.map