name: Deploy to Kubernetes

on:
  workflow_dispatch:
    inputs:
      mode:
        description: 'Deployment mode'
        required: true
        default: 'multiuser'
        type: choice
        options:
          - solo
          - multiuser
          - enterprise
      dry_run:
        description: 'Perform dry-run (no actual deployment)'
        required: false
        default: 'true'
        type: choice
        options:
          - 'true'
          - 'false'
      environment:
        description: 'Target environment'
        required: true
        type: choice
        options:
          - staging
          - production
      rollout_timeout:
        description: 'Rollout timeout in seconds'
        required: false
        default: '300'
        type: string

concurrency:
  group: k8s-deployment-${{ github.ref }}-${{ inputs.environment }}
  cancel-in-progress: false

jobs:
  deploy-kubernetes:
    name: Deploy ${{ inputs.mode || 'multiuser' }} to K8s
    runs-on: ubuntu-latest
    environment: ${{ inputs.environment || 'staging' }}
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Download artifacts
        uses: actions/download-artifact@v4
        with:
          name: deployment-artifacts
          path: artifacts/

      - name: Install Nushell
        run: |
          cargo install nu --locked
          nu --version

      - name: Install kubectl
        uses: azure/setup-kubectl@v3
        with:
          version: 'latest'

      - name: Configure kubeconfig
        run: |
          mkdir -p ~/.kube
          echo "${{ secrets.KUBE_CONFIG_STAGING }}" | base64 -d > ~/.kube/config
          chmod 600 ~/.kube/config
          kubectl cluster-info
        if: ${{ inputs.environment == 'staging' }}

      - name: Configure kubeconfig (production)
        run: |
          mkdir -p ~/.kube
          echo "${{ secrets.KUBE_CONFIG_PRODUCTION }}" | base64 -d > ~/.kube/config
          chmod 600 ~/.kube/config
          kubectl cluster-info
        if: ${{ inputs.environment == 'production' }}

      - name: Create VAPORA namespace
        run: |
          kubectl create namespace vapora --dry-run=client -o yaml | kubectl apply -f -
          kubectl label namespace vapora environment=${{ inputs.environment }} --overwrite

      - name: Create deployment directory
        run: |
          mkdir -p deploy/kubernetes
          cp artifacts/configmap.yaml deploy/kubernetes/
          cp artifacts/deployment.yaml deploy/kubernetes/
          cp artifacts/vapora-${{ inputs.mode || 'multiuser' }}.yaml deploy/kubernetes/config.yaml

      - name: Validate Kubernetes manifests
        run: |
          kubectl apply --dry-run=client -f deploy/kubernetes/configmap.yaml
          kubectl apply --dry-run=client -f deploy/kubernetes/deployment.yaml
          echo "✓ Kubernetes manifests validated"

      - name: Show deployment diff (dry-run)
        if: ${{ inputs.dry_run == 'true' }}
        run: |
          echo "🔍 Deployment diff (dry-run):"
          kubectl apply --dry-run=server -f deploy/kubernetes/configmap.yaml -o yaml
          kubectl apply --dry-run=server -f deploy/kubernetes/deployment.yaml -o yaml

      - name: Deploy ConfigMap
        if: ${{ inputs.dry_run == 'false' }}
        run: |
          echo "📋 Deploying ConfigMap..."
          kubectl apply -f deploy/kubernetes/configmap.yaml
          sleep 5
          kubectl get configmap -n vapora

      - name: Deploy Deployments
        if: ${{ inputs.dry_run == 'false' }}
        run: |
          echo "🚀 Deploying services..."
          kubectl apply -f deploy/kubernetes/deployment.yaml
          kubectl get deployments -n vapora

      - name: Wait for rollout (backend)
        if: ${{ inputs.dry_run == 'false' }}
        run: |
          echo "⏳ Waiting for backend deployment..."
          kubectl rollout status deployment/vapora-backend -n vapora --timeout=${{ inputs.rollout_timeout }}s

      - name: Wait for rollout (agents)
        if: ${{ inputs.dry_run == 'false' }}
        run: |
          echo "⏳ Waiting for agents deployment..."
          kubectl rollout status deployment/vapora-agents -n vapora --timeout=${{ inputs.rollout_timeout }}s

      - name: Wait for rollout (llm-router)
        if: ${{ inputs.dry_run == 'false' }}
        run: |
          echo "⏳ Waiting for llm-router deployment..."
          kubectl rollout status deployment/vapora-llm-router -n vapora --timeout=${{ inputs.rollout_timeout }}s

      - name: Verify pod health
        if: ${{ inputs.dry_run == 'false' }}
        run: |
          echo "🏥 Checking pod health..."
          kubectl get pods -n vapora
          echo ""
          echo "Pod details:"
          kubectl describe pods -n vapora | grep -A 5 "Status:"

      - name: Check deployment status
        if: always()
        run: |
          echo "📊 Deployment Status:"
          kubectl get deployments -n vapora -o wide
          echo ""
          echo "📋 Services:"
          kubectl get services -n vapora
          echo ""
          echo "🔧 ConfigMaps:"
          kubectl get configmaps -n vapora

      - name: Get service endpoints
        if: ${{ inputs.dry_run == 'false' }}
        run: |
          echo "🌐 Service Endpoints:"
          kubectl get services -n vapora -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.clusterIP}{"\n"}{end}'

      - name: Save deployment manifest
        if: success()
        run: |
          cat > deploy/kubernetes/DEPLOYMENT.md << 'EOF'
          # Kubernetes Deployment Details

          **Deployment Time**: $(date -u +'%Y-%m-%dT%H:%M:%SZ')
          **Mode**: ${{ inputs.mode || 'multiuser' }}
          **Environment**: ${{ inputs.environment || 'staging' }}
          **Namespace**: vapora
          **Commit**: ${{ github.sha }}
          **Workflow Run**: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}

          ## Deployment Status

          ### Deployments
          - **vapora-backend** - REST API server
          - **vapora-agents** - Agent orchestration
          - **vapora-llm-router** - LLM provider routing

          ### Configuration
          - **ConfigMap**: vapora-config (environment data)
          - **Namespace**: vapora (isolated environment)

          ## Kubernetes Commands

          ### View logs
          ```bash
          # Backend logs
          kubectl logs -f deployment/vapora-backend -n vapora

          # Agents logs
          kubectl logs -f deployment/vapora-agents -n vapora

          # All pod logs
          kubectl logs -f -l app=vapora -n vapora
          ```

          ### Check deployment status
          ```bash
          kubectl get deployments -n vapora
          kubectl get pods -n vapora
          kubectl describe deployment vapora-backend -n vapora
          ```

          ### Rollback if needed
          ```bash
          kubectl rollout undo deployment/vapora-backend -n vapora
          kubectl rollout history deployment/vapora-backend -n vapora
          ```

          ### Port forwarding
          ```bash
          kubectl port-forward -n vapora svc/vapora-backend 8001:8001
          kubectl port-forward -n vapora svc/vapora-frontend 3000:3000
          ```

          ### Scale deployment
          ```bash
          kubectl scale deployment vapora-backend --replicas=3 -n vapora
          ```

          ## Access Services

          ### Internal (ClusterIP)
          - **Backend**: http://vapora-backend.vapora.svc.cluster.local:8001
          - **Agents**: http://vapora-agents.vapora.svc.cluster.local:8002
          - **LLM Router**: http://vapora-llm-router.vapora.svc.cluster.local:8003
          - **Frontend**: http://vapora-frontend.vapora.svc.cluster.local:3000

          ### External (requires Ingress/LoadBalancer)
          - Configure Ingress or LoadBalancer service
          - See production documentation for external access setup

          EOF
          cat deploy/kubernetes/DEPLOYMENT.md

      - name: Upload deployment manifests
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: k8s-deployment-${{ inputs.environment }}-${{ github.run_id }}
          path: deploy/kubernetes/
          retention-days: 30

      - name: Create deployment annotation
        if: ${{ inputs.dry_run == 'false' && success() }}
        run: |
          kubectl annotate deployment vapora-backend \
            -n vapora \
            deployment.kubernetes.io/revision=$(date +%s) \
            github.deployment.run=${{ github.run_id }} \
            github.deployment.commit=${{ github.sha }} \
            --overwrite

      - name: Post deployment summary
        if: always()
        uses: actions/github-script@v7
        with:
          script: |
            const mode = '${{ inputs.mode || "multiuser" }}';
            const env = '${{ inputs.environment || "staging" }}';
            const isDryRun = '${{ inputs.dry_run }}' === 'true';

            let message = `${isDryRun ? '🔍' : '✅'} **Kubernetes deployment ${isDryRun ? 'validated' : 'successful'}!**\n\n`;
            message += `**Mode**: ${mode}\n`;
            message += `**Environment**: ${env}\n`;
            message += `**Dry-run**: ${isDryRun ? 'Yes' : 'No'}\n`;
            message += `**Namespace**: vapora\n\n`;

            message += `**Deployments**:\n`;
            message += `- vapora-backend\n`;
            message += `- vapora-agents\n`;
            message += `- vapora-llm-router\n\n`;

            message += `**Useful Commands**:\n`;
            message += `\`\`\`bash\n`;
            message += `# View deployment status\n`;
            message += `kubectl get deployments -n vapora\n\n`;
            message += `# View logs\n`;
            message += `kubectl logs -f deployment/vapora-backend -n vapora\n\n`;
            message += `# Port forward\n`;
            message += `kubectl port-forward -n vapora svc/vapora-backend 8001:8001\n`;
            message += `\`\`\`\n`;

            // Only post to PR if it's a PR event
            if (context.eventName === 'pull_request' || context.payload.pull_request) {
              github.rest.issues.createComment({
                issue_number: context.issue.number,
                owner: context.repo.owner,
                repo: context.repo.repo,
                body: message
              });
            }

      - name: Notify Slack on success
        if: success()
        uses: 8398a7/action-slack@v3
        with:
          status: ${{ job.status }}
          text: |
            VAPORA Kubernetes deployment successful!
            Mode: ${{ inputs.mode || 'multiuser' }}
            Environment: ${{ inputs.environment || 'staging' }}
            Namespace: vapora
          webhook_url: ${{ secrets.SLACK_WEBHOOK }}
          fields: repo,message,commit,author
        continue-on-error: true

      - name: Notify Slack on failure
        if: failure()
        uses: 8398a7/action-slack@v3
        with:
          status: ${{ job.status }}
          text: |
            VAPORA Kubernetes deployment failed!
            Mode: ${{ inputs.mode || 'multiuser' }}
            Environment: ${{ inputs.environment || 'staging' }}
          webhook_url: ${{ secrets.SLACK_WEBHOOK }}
          fields: repo,message,commit,author
        continue-on-error: true
