import { CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js';
import { ConfigManager } from '../../config/config-manager.js';
import { StorageManager } from '../../storage/storage-manager.js';
import { DeploymentManager } from './deployment-manager.js';
import { MigrationManager } from '../migration-management/migration-manager.js';
import crypto from 'crypto';
import path from 'path';
let configManager;
let storageManager;
let deploymentManager;
let migrationManager;
export async function setupDeploymentTools(server, config) {
    configManager = config || new ConfigManager();
    storageManager = new StorageManager();
    // Initialize deployment config
    const projectMarker = await storageManager.loadProjectMarker();
    const deploymentConfig = {
        projectId: projectMarker?.projectId || 'default',
        provider: 'custom', // Default provider
        settings: {},
        environments: [],
    };
    deploymentManager = new DeploymentManager(deploymentConfig);
    // Initialize migration config
    const migrationConfig = {
        migrationsPath: path.join(process.cwd(), 'migrations'),
        validation: {
            checksumValidation: true,
            syntaxCheck: true,
            dryRun: false,
            requireRollback: true,
        },
    };
    migrationManager = new MigrationManager(migrationConfig);
    server.setRequestHandler(CallToolRequestSchema, async (request) => {
        const { name, arguments: args } = request.params;
        if (!args) {
            throw new Error('No arguments provided');
        }
        switch (name) {
            case 'setup_deployment': {
                const { provider, environments, apiKey, projectName, buildCommand, outputDirectory, } = args;
                // Create deployment environments
                const deploymentEnvironments = environments.map(env => ({
                    id: crypto.randomUUID(),
                    name: env.name,
                    type: env.type,
                    url: env.url,
                    branch: env.branch,
                    variables: [],
                    status: 'inactive',
                    createdAt: new Date().toISOString(),
                    updatedAt: new Date().toISOString(),
                }));
                // Update deployment config
                deploymentConfig.provider = provider;
                deploymentConfig.settings = {
                    apiKey,
                    projectName,
                    buildCommand,
                    outputDirectory,
                };
                deploymentConfig.environments = deploymentEnvironments;
                // Save configuration
                await storageManager.saveData('deployment-management', 'deployment-config.json', deploymentConfig);
                return {
                    content: [
                        {
                            type: 'text',
                            text: `✅ Deployment configured\n\n**Provider**: ${provider}\n**Environments**: ${environments.map(e => e.name).join(', ')}\n\nYou can now deploy to these environments using the deploy_to_environment tool.`,
                        },
                    ],
                    structured: {
                        provider,
                        environments: deploymentEnvironments,
                        timestamp: new Date().toISOString(),
                    },
                };
            }
            case 'deploy_to_environment': {
                const { environment, version, force = false, skipHealthChecks = false, dryRun = false, author, } = args;
                try {
                    const deployment = await deploymentManager.deploy(environment, version, {
                        force,
                        skipHealthChecks,
                        dryRun,
                        author,
                    });
                    const output = formatDeploymentOutput(deployment, dryRun);
                    return {
                        content: [
                            {
                                type: 'text',
                                text: output,
                            },
                        ],
                        structured: {
                            deployment,
                            dryRun,
                            timestamp: new Date().toISOString(),
                        },
                    };
                }
                catch (error) {
                    return {
                        content: [
                            {
                                type: 'text',
                                text: `❌ Deployment failed\n\n**Error**: ${error.message}`,
                            },
                        ],
                        structured: {
                            error: error.message,
                            environment,
                            version,
                            timestamp: new Date().toISOString(),
                        },
                    };
                }
            }
            case 'rollback_deployment': {
                const { environment, targetVersion, skipHealthChecks = false, author, } = args;
                try {
                    const deployment = await deploymentManager.rollback(environment, targetVersion, {
                        skipHealthChecks,
                        author,
                    });
                    return {
                        content: [
                            {
                                type: 'text',
                                text: `✅ Rollback completed\n\n**Environment**: ${environment}\n**Rolled back to**: ${targetVersion}\n**Duration**: ${deployment.duration}ms\n\nEnvironment is now running version ${targetVersion}.`,
                            },
                        ],
                        structured: {
                            deployment,
                            timestamp: new Date().toISOString(),
                        },
                    };
                }
                catch (error) {
                    return {
                        content: [
                            {
                                type: 'text',
                                text: `❌ Rollback failed\n\n**Error**: ${error.message}`,
                            },
                        ],
                        structured: {
                            error: error.message,
                            environment,
                            targetVersion,
                            timestamp: new Date().toISOString(),
                        },
                    };
                }
            }
            case 'get_deployment_status': {
                const { environment } = args;
                const metrics = await deploymentManager.getDeploymentMetrics(environment);
                const output = formatDeploymentMetrics(metrics);
                return {
                    content: [
                        {
                            type: 'text',
                            text: output,
                        },
                    ],
                    structured: {
                        metrics,
                        timestamp: new Date().toISOString(),
                    },
                };
            }
            case 'plan_deployment': {
                const { environment, version, previousVersion } = args;
                try {
                    const plan = await deploymentManager.createDeploymentPlan(environment, version, previousVersion);
                    const output = formatDeploymentPlan(plan);
                    return {
                        content: [
                            {
                                type: 'text',
                                text: output,
                            },
                        ],
                        structured: {
                            plan,
                            timestamp: new Date().toISOString(),
                        },
                    };
                }
                catch (error) {
                    return {
                        content: [
                            {
                                type: 'text',
                                text: `❌ Failed to create deployment plan\n\n**Error**: ${error.message}`,
                            },
                        ],
                        structured: {
                            error: error.message,
                            timestamp: new Date().toISOString(),
                        },
                    };
                }
            }
            case 'generate_release_notes': {
                const { version, previousVersion } = args;
                try {
                    const releaseNotes = await deploymentManager.generateReleaseNotes(version, previousVersion);
                    const output = formatReleaseNotes(releaseNotes);
                    return {
                        content: [
                            {
                                type: 'text',
                                text: output,
                            },
                        ],
                        structured: {
                            releaseNotes,
                            timestamp: new Date().toISOString(),
                        },
                    };
                }
                catch (error) {
                    return {
                        content: [
                            {
                                type: 'text',
                                text: `❌ Failed to generate release notes\n\n**Error**: ${error.message}`,
                            },
                        ],
                        structured: {
                            error: error.message,
                            timestamp: new Date().toISOString(),
                        },
                    };
                }
            }
            case 'create_migration': {
                const { name, type, description } = args;
                try {
                    const migration = await migrationManager.createMigration(name, type);
                    if (description) {
                        migration.description = description;
                    }
                    return {
                        content: [
                            {
                                type: 'text',
                                text: `✅ Migration created\n\n**Version**: ${migration.version}\n**Name**: ${migration.name}\n**Type**: ${migration.type}\n**File**: migrations/${migration.version}_${name.toLowerCase().replace(/\s+/g, '_')}.js\n\nEdit the migration file to add your up and down logic.`,
                            },
                        ],
                        structured: {
                            migration,
                            timestamp: new Date().toISOString(),
                        },
                    };
                }
                catch (error) {
                    return {
                        content: [
                            {
                                type: 'text',
                                text: `❌ Failed to create migration\n\n**Error**: ${error.message}`,
                            },
                        ],
                        structured: {
                            error: error.message,
                            timestamp: new Date().toISOString(),
                        },
                    };
                }
            }
            case 'run_migrations': {
                const { target, dryRun = false, force = false } = args;
                try {
                    const records = await migrationManager.runMigrations({ target, dryRun, force });
                    const output = formatMigrationOutput(records, dryRun);
                    return {
                        content: [
                            {
                                type: 'text',
                                text: output,
                            },
                        ],
                        structured: {
                            records,
                            dryRun,
                            timestamp: new Date().toISOString(),
                        },
                    };
                }
                catch (error) {
                    return {
                        content: [
                            {
                                type: 'text',
                                text: `❌ Migration failed\n\n**Error**: ${error.message}`,
                            },
                        ],
                        structured: {
                            error: error.message,
                            timestamp: new Date().toISOString(),
                        },
                    };
                }
            }
            case 'rollback_migrations': {
                const { steps, target, force = false } = args;
                try {
                    const records = await migrationManager.rollback({ steps, target, force });
                    const output = formatRollbackOutput(records);
                    return {
                        content: [
                            {
                                type: 'text',
                                text: output,
                            },
                        ],
                        structured: {
                            records,
                            timestamp: new Date().toISOString(),
                        },
                    };
                }
                catch (error) {
                    return {
                        content: [
                            {
                                type: 'text',
                                text: `❌ Rollback failed\n\n**Error**: ${error.message}`,
                            },
                        ],
                        structured: {
                            error: error.message,
                            timestamp: new Date().toISOString(),
                        },
                    };
                }
            }
            case 'migration_status': {
                const status = await migrationManager.getMigrationStatus();
                return {
                    content: [
                        {
                            type: 'text',
                            text: `📊 Migration Status\n\n**Current Version**: ${status.current}\n**Pending Migrations**: ${status.pending}\n**Executed Migrations**: ${status.executed}\n**Failed Migrations**: ${status.failed}\n\n${status.pending > 0 ? `Run \`run_migrations\` to execute ${status.pending} pending migration(s).` : 'All migrations are up to date.'}`,
                        },
                    ],
                    structured: {
                        status,
                        timestamp: new Date().toISOString(),
                    },
                };
            }
            default:
                return null;
        }
    });
    return {
        tools: [
            {
                name: 'setup_deployment',
                description: 'Configure deployment settings and environments',
                inputSchema: {
                    type: 'object',
                    properties: {
                        provider: {
                            type: 'string',
                            enum: ['vercel', 'netlify', 'heroku', 'aws', 'docker', 'kubernetes', 'custom'],
                            description: 'Deployment provider',
                        },
                        environments: {
                            type: 'array',
                            items: {
                                type: 'object',
                                properties: {
                                    name: { type: 'string' },
                                    type: { type: 'string', enum: ['development', 'staging', 'production', 'custom'] },
                                    url: { type: 'string' },
                                    branch: { type: 'string' },
                                },
                                required: ['name', 'type'],
                            },
                            description: 'Deployment environments',
                        },
                        apiKey: { type: 'string', description: 'API key for deployment provider' },
                        projectName: { type: 'string', description: 'Project name on deployment platform' },
                        buildCommand: { type: 'string', description: 'Build command' },
                        outputDirectory: { type: 'string', description: 'Build output directory' },
                    },
                    required: ['provider', 'environments'],
                },
            },
            {
                name: 'deploy_to_environment',
                description: 'Deploy a specific version to an environment',
                inputSchema: {
                    type: 'object',
                    properties: {
                        environment: { type: 'string', description: 'Target environment name' },
                        version: { type: 'string', description: 'Version to deploy' },
                        force: { type: 'boolean', description: 'Force deployment even if environment is busy', default: false },
                        skipHealthChecks: { type: 'boolean', description: 'Skip health checks', default: false },
                        dryRun: { type: 'boolean', description: 'Simulate deployment without executing', default: false },
                        author: { type: 'string', description: 'Person initiating the deployment' },
                    },
                    required: ['environment', 'version'],
                },
            },
            {
                name: 'rollback_deployment',
                description: 'Rollback an environment to a previous version',
                inputSchema: {
                    type: 'object',
                    properties: {
                        environment: { type: 'string', description: 'Target environment name' },
                        targetVersion: { type: 'string', description: 'Version to rollback to' },
                        skipHealthChecks: { type: 'boolean', description: 'Skip health checks', default: false },
                        author: { type: 'string', description: 'Person initiating the rollback' },
                    },
                    required: ['environment', 'targetVersion'],
                },
            },
            {
                name: 'get_deployment_status',
                description: 'Get deployment metrics and recent deployments',
                inputSchema: {
                    type: 'object',
                    properties: {
                        environment: { type: 'string', description: 'Filter by environment (optional)' },
                    },
                    required: []
                },
            },
            {
                name: 'plan_deployment',
                description: 'Create a deployment plan with risk assessment',
                inputSchema: {
                    type: 'object',
                    properties: {
                        environment: { type: 'string', description: 'Target environment' },
                        version: { type: 'string', description: 'Version to deploy' },
                        previousVersion: { type: 'string', description: 'Current version (optional)' },
                    },
                    required: ['environment', 'version'],
                },
            },
            {
                name: 'generate_release_notes',
                description: 'Generate release notes between versions',
                inputSchema: {
                    type: 'object',
                    properties: {
                        version: { type: 'string', description: 'New version' },
                        previousVersion: { type: 'string', description: 'Previous version (optional)' },
                    },
                    required: ['version'],
                },
            },
            {
                name: 'create_migration',
                description: 'Create a new database/data migration',
                inputSchema: {
                    type: 'object',
                    properties: {
                        name: { type: 'string', description: 'Migration name' },
                        type: {
                            type: 'string',
                            enum: ['schema', 'data', 'seed', 'index', 'procedure', 'config'],
                            description: 'Type of migration',
                        },
                        description: { type: 'string', description: 'Migration description' },
                    },
                    required: ['name', 'type'],
                },
            },
            {
                name: 'run_migrations',
                description: 'Execute pending migrations',
                inputSchema: {
                    type: 'object',
                    properties: {
                        target: { type: 'string', description: 'Run up to specific version' },
                        dryRun: { type: 'boolean', description: 'Simulate without executing', default: false },
                        force: { type: 'boolean', description: 'Skip validation checks', default: false },
                    },
                    required: []
                },
            },
            {
                name: 'rollback_migrations',
                description: 'Rollback executed migrations',
                inputSchema: {
                    type: 'object',
                    properties: {
                        steps: { type: 'number', description: 'Number of migrations to rollback' },
                        target: { type: 'string', description: 'Rollback to specific version' },
                        force: { type: 'boolean', description: 'Force rollback without down script', default: false },
                    },
                    required: []
                },
            },
            {
                name: 'migration_status',
                description: 'Get current migration status',
                inputSchema: {
                    type: 'object',
                    properties: {},
                    required: []
                },
            },
        ],
        resources: [],
    };
}
// Helper functions
function formatDeploymentOutput(deployment, dryRun) {
    if (dryRun) {
        return `🚀 Deployment Plan (DRY RUN)\n\n**Version**: ${deployment.version}\n**Status**: ${deployment.status}\n\nThis is a dry run. No actual deployment was performed.`;
    }
    const icon = deployment.status === 'success' ? '✅' : deployment.status === 'failed' ? '❌' : '🔄';
    let output = `${icon} Deployment ${deployment.status}\n\n`;
    output += `**Version**: ${deployment.version}\n`;
    output += `**Environment**: ${deployment.environmentId}\n`;
    if (deployment.duration) {
        output += `**Duration**: ${(deployment.duration / 1000).toFixed(2)}s\n`;
    }
    if (deployment.logs && deployment.logs.length > 0) {
        output += `\n📋 **Deployment Logs**\n`;
        deployment.logs.forEach(log => {
            const logIcon = log.level === 'error' ? '❌' : log.level === 'warning' ? '⚠️' : '✅';
            output += `${logIcon} ${log.message}\n`;
        });
    }
    return output;
}
function formatDeploymentMetrics(metrics) {
    let output = `📊 Deployment Metrics\n\n`;
    output += `**Total Deployments**: ${metrics.totalDeployments}\n`;
    output += `**Success Rate**: ${metrics.successRate.toFixed(1)}%\n`;
    output += `**Average Duration**: ${(metrics.averageDuration / 1000).toFixed(2)}s\n\n`;
    if (Object.keys(metrics.deploymentsByEnvironment).length > 0) {
        output += `**Deployments by Environment**\n`;
        Object.entries(metrics.deploymentsByEnvironment).forEach(([env, count]) => {
            output += `• ${env}: ${count}\n`;
        });
        output += `\n`;
    }
    if (metrics.recentDeployments.length > 0) {
        output += `**Recent Deployments**\n`;
        metrics.recentDeployments.slice(0, 5).forEach(deployment => {
            const icon = deployment.status === 'success' ? '✅' : '❌';
            const date = new Date(deployment.startedAt);
            output += `${icon} ${deployment.version} - ${date.toLocaleDateString()} ${date.toLocaleTimeString()}\n`;
        });
    }
    return output;
}
function formatDeploymentPlan(plan) {
    let output = `📋 Deployment Plan\n\n`;
    output += `**Environment**: ${plan.environment}\n`;
    output += `**Version**: ${plan.version}\n`;
    output += `**Estimated Duration**: ${(plan.estimatedDuration / 1000).toFixed(0)}s\n`;
    output += `**Approval Required**: ${plan.approvalRequired ? 'Yes' : 'No'}\n\n`;
    if (plan.changes.length > 0) {
        output += `**Changes** (${plan.changes.length})\n`;
        plan.changes.forEach(change => {
            const icon = change.type === 'feature' ? '✨' :
                change.type === 'bugfix' ? '🐛' :
                    change.type === 'config' ? '⚙️' : '🏗️';
            output += `${icon} ${change.description} (${change.impact} impact)\n`;
        });
        output += `\n`;
    }
    if (plan.risks.length > 0) {
        output += `**Risks**\n`;
        plan.risks.forEach(risk => {
            const icon = risk.impact === 'high' ? '🔴' :
                risk.impact === 'medium' ? '🟡' : '🟢';
            output += `${icon} ${risk.description}\n`;
            if (risk.mitigation) {
                output += `   Mitigation: ${risk.mitigation}\n`;
            }
        });
        output += `\n`;
    }
    if (plan.rollbackPlan) {
        output += `**Rollback Plan**\n`;
        output += `• Strategy: ${plan.rollbackPlan.strategy}\n`;
        output += `• Target Version: ${plan.rollbackPlan.targetVersion}\n`;
        output += `• Estimated Duration: ${(plan.rollbackPlan.estimatedDuration / 1000).toFixed(0)}s\n`;
    }
    return output;
}
function formatReleaseNotes(releaseNotes) {
    let output = `📝 Release Notes - v${releaseNotes.version}\n\n`;
    output += `**Date**: ${new Date(releaseNotes.date).toLocaleDateString()}\n\n`;
    if (releaseNotes.changes.features.length > 0) {
        output += `**✨ New Features**\n`;
        releaseNotes.changes.features.forEach(feature => {
            output += `• ${feature}\n`;
        });
        output += `\n`;
    }
    if (releaseNotes.changes.fixes.length > 0) {
        output += `**🐛 Bug Fixes**\n`;
        releaseNotes.changes.fixes.forEach(fix => {
            output += `• ${fix}\n`;
        });
        output += `\n`;
    }
    if (releaseNotes.changes.breaking.length > 0) {
        output += `**💥 Breaking Changes**\n`;
        releaseNotes.changes.breaking.forEach(breaking => {
            output += `• ${breaking}\n`;
        });
        output += `\n`;
    }
    if (releaseNotes.contributors.length > 0) {
        output += `**👥 Contributors**\n`;
        output += releaseNotes.contributors.join(', ') + '\n';
    }
    return output;
}
function formatMigrationOutput(records, dryRun) {
    if (dryRun) {
        return `🔄 Migration Plan (DRY RUN)\n\n${records.length} migration(s) would be executed.\n\nThis is a dry run. No migrations were actually executed.`;
    }
    if (records.length === 0) {
        return '✅ No pending migrations to run.';
    }
    let output = `✅ Migrations completed\n\n`;
    records.forEach(record => {
        const icon = record.status === 'completed' ? '✅' :
            record.status === 'failed' ? '❌' : '⏭️';
        output += `${icon} ${record.version} - ${record.name}\n`;
        if (record.error) {
            output += `   Error: ${record.error}\n`;
        }
    });
    const successful = records.filter(r => r.status === 'completed').length;
    output += `\n${successful}/${records.length} migrations completed successfully.`;
    return output;
}
function formatRollbackOutput(records) {
    if (records.length === 0) {
        return '✅ No migrations to rollback.';
    }
    let output = `✅ Rollback completed\n\n`;
    records.forEach(record => {
        const icon = record.status === 'rolled_back' ? '✅' : '❌';
        output += `${icon} ${record.version} - ${record.name}\n`;
        if (record.error) {
            output += `   Error: ${record.error}\n`;
        }
    });
    const successful = records.filter(r => r.status === 'rolled_back').length;
    output += `\n${successful}/${records.length} migrations rolled back successfully.`;
    return output;
}
//# sourceMappingURL=index.js.map