/**
 * Docker Deploy Command
 * Deploy containers with zero-downtime support
 */

import { exec } from 'child_process'
import { promisify } from 'util'
import { readFileSync, writeFileSync } from 'fs'

const execAsync = promisify(exec)

export interface DeployOptions {
  env?: string
  noDowntime?: boolean
  force?: boolean
  build?: boolean
  scale?: number
}

export async function handle(args: DeployOptions, context: any): Promise<string> {
  const { env = 'production', noDowntime = true, force = false, build = true, scale } = args

  try {
    const results: string[] = []

    // Build if requested
    if (build) {
      results.push('Building Docker image...')
      const { stdout: buildOutput } = await execAsync('docker-compose build')
      results.push(buildOutput)
    }

    if (noDowntime && !force) {
      // Zero-downtime deployment
      results.push('Starting zero-downtime deployment...')

      // Get current running containers
      const { stdout: psOutput } = await execAsync('docker-compose ps -q')
      const hasRunning = psOutput.trim().length > 0

      if (hasRunning) {
        // Start new containers alongside old ones
        results.push('Starting new containers...')
        await execAsync(`docker-compose up -d --scale app=${scale || 2} --no-recreate`)

        // Wait for health checks
        await new Promise(resolve => setTimeout(resolve, 5000))

        // Stop old containers gracefully
        results.push('Stopping old containers...')
        await execAsync('docker-compose up -d --scale app=1 --no-recreate')
      } else {
        // First deployment
        results.push('Initial deployment...')
        await execAsync('docker-compose up -d')
      }
    } else {
      // Standard deployment with potential downtime
      results.push('Deploying with potential downtime...')
      await execAsync('docker-compose up -d --force-recreate')
    }

    // Show status
    const { stdout: statusOutput } = await execAsync('docker-compose ps')
    results.push('\n✓ Deployment complete!\n')
    results.push(statusOutput)

    return results.join('\n')
  } catch (error: any) {
    throw new Error(`Docker deployment failed: ${error.message}`)
  }
}

export default { handle }
