# VAPORA Woodpecker Pipeline - Deploy to Kubernetes
# Deploys VAPORA to Kubernetes cluster with dry-run and verification
# Triggers on: manual promotion

trigger:
  event: [promote]
  branch: [main, develop]

variables:
  ARTIFACTS_DIR: provisioning/artifacts
  LOGS_DIR: provisioning/logs
  VAPORA_NAMESPACE: vapora

stages:
  setup:
    steps:
      - name: prepare
        image: alpine:latest
        commands:
          - mkdir -p ${ARTIFACTS_DIR} ${LOGS_DIR}
          - echo "☸️  VAPORA Kubernetes Deployment Pipeline"
          - echo "Commit: ${CI_COMMIT_SHA:0:8}"
          - echo "Branch: ${CI_COMMIT_BRANCH}"
          - echo "Event: ${CI_PIPELINE_EVENT}"

  install_dependencies:
    steps:
      - name: install_tools
        image: rust:latest
        commands:
          - apt-get update && apt-get install -y curl jq yq
          - cargo install nu --locked
          - pip install jinja2-cli
          - curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
          - chmod +x kubectl && mv kubectl /usr/local/bin/
          - nu --version
          - kubectl version --client
          - jinja2 --version
          - yq --version

  configure_kubernetes:
    depends_on: [install_dependencies]
    steps:
      - name: setup_kubeconfig_staging
        image: alpine:latest
        environment:
          KUBE_CONFIG_STAGING: ${KUBE_CONFIG_STAGING}
        commands:
          - mkdir -p ~/.kube
          - echo "$KUBE_CONFIG_STAGING" | base64 -d > ~/.kube/config
          - chmod 600 ~/.kube/config
          - echo "✓ Kubeconfig configured for staging"
        when:
          evaluate: 'return build.Deploy_Environment == "staging"'

      - name: setup_kubeconfig_production
        image: alpine:latest
        environment:
          KUBE_CONFIG_PRODUCTION: ${KUBE_CONFIG_PRODUCTION}
        commands:
          - mkdir -p ~/.kube
          - echo "$KUBE_CONFIG_PRODUCTION" | base64 -d > ~/.kube/config
          - chmod 600 ~/.kube/config
          - echo "✓ Kubeconfig configured for production"
        when:
          evaluate: 'return build.Deploy_Environment == "production"'

      - name: verify_cluster
        image: alpine:latest
        commands:
          - apk add --no-cache curl
          - kubectl cluster-info
          - kubectl get nodes
          - echo "✓ Kubernetes cluster accessible"

  validate_manifests:
    depends_on: [configure_kubernetes]
    steps:
      - name: validate_kubernetes_manifests
        image: rust:latest
        environment:
          RUST_LOG: warn
        commands:
          - apt-get update && apt-get install -y curl jq yq
          - cargo install nu --locked > /dev/null 2>&1
          - cargo install nickel --locked > /dev/null 2>&1
          - pip install jinja2-cli > /dev/null 2>&1
          - |
            echo "Validating Kubernetes manifests..."
            if [ -f "${ARTIFACTS_DIR}/deployment.yaml" ]; then
              yq eval '.' "${ARTIFACTS_DIR}/deployment.yaml" > /dev/null && echo "✓ Deployment manifest valid"
              yq eval '.' "${ARTIFACTS_DIR}/configmap.yaml" > /dev/null && echo "✓ ConfigMap manifest valid"
            else
              echo "⚠️  Manifests not found, generating from Nickel"
              cd provisioning
              nu scripts/ci-pipeline.nu --artifact-dir ../${ARTIFACTS_DIR} --mode multiuser 2>&1 | tee ../${LOGS_DIR}/k8s-generation.log
            fi

      - name: dry_run_validation
        image: alpine:latest
        commands:
          - apk add --no-cache curl
          - |
            echo "🔍 Performing dry-run validation..."
            kubectl apply -f ${ARTIFACTS_DIR}/deployment.yaml --dry-run=server -n ${VAPORA_NAMESPACE} --record 2>&1 | tee ${LOGS_DIR}/dry-run-validation.log
            if [ $? -eq 0 ]; then
              echo "✓ Dry-run validation passed"
            else
              echo "❌ Dry-run validation failed"
              exit 1
            fi

  create_namespace:
    depends_on: [validate_manifests]
    steps:
      - name: ensure_namespace
        image: alpine:latest
        commands:
          - apk add --no-cache curl
          - |
            echo "📁 Creating/verifying vapora namespace..."
            kubectl get namespace ${VAPORA_NAMESPACE} > /dev/null 2>&1 || kubectl create namespace ${VAPORA_NAMESPACE}
            echo "✓ Namespace ready"

      - name: setup_rbac
        image: alpine:latest
        commands:
          - apk add --no-cache curl
          - |
            echo "🔐 Setting up RBAC..."
            # Default service account has basic access
            kubectl get serviceaccount default -n ${VAPORA_NAMESPACE} > /dev/null 2>&1 || {
              echo "Creating default service account"
              kubectl create serviceaccount default -n ${VAPORA_NAMESPACE}
            }
            echo "✓ RBAC configured"

  deploy_configmap:
    depends_on: [create_namespace]
    steps:
      - name: apply_configmap
        image: alpine:latest
        commands:
          - apk add --no-cache curl
          - |
            echo "⚙️  Applying ConfigMap..."
            kubectl apply -f ${ARTIFACTS_DIR}/configmap.yaml -n ${VAPORA_NAMESPACE} --record
            echo "✓ ConfigMap applied"

      - name: verify_configmap
        image: alpine:latest
        commands:
          - apk add --no-cache curl
          - |
            echo "✓ ConfigMap contents:"
            kubectl get configmap -n ${VAPORA_NAMESPACE} -o yaml | head -50

  deploy_services:
    depends_on: [deploy_configmap]
    steps:
      - name: apply_deployments
        image: alpine:latest
        commands:
          - apk add --no-cache curl
          - |
            echo "🚀 Applying Kubernetes Deployments..."
            kubectl apply -f ${ARTIFACTS_DIR}/deployment.yaml -n ${VAPORA_NAMESPACE} --record
            echo "✓ Deployments applied"

      - name: monitor_rollout_backend
        image: alpine:latest
        commands:
          - apk add --no-cache curl
          - |
            echo "⏳ Waiting for backend rollout..."
            kubectl rollout status deployment/vapora-backend -n ${VAPORA_NAMESPACE} --timeout=5m
            echo "✓ Backend deployment ready"

      - name: monitor_rollout_agents
        image: alpine:latest
        commands:
          - apk add --no-cache curl
          - |
            echo "⏳ Waiting for agents rollout..."
            kubectl rollout status deployment/vapora-agents -n ${VAPORA_NAMESPACE} --timeout=5m
            echo "✓ Agents deployment ready"

      - name: monitor_rollout_llm_router
        image: alpine:latest
        commands:
          - apk add --no-cache curl
          - |
            echo "⏳ Waiting for LLM router rollout..."
            kubectl rollout status deployment/vapora-llm-router -n ${VAPORA_NAMESPACE} --timeout=5m
            echo "✓ LLM router deployment ready"

  verify_deployment:
    depends_on: [deploy_services]
    steps:
      - name: check_pods
        image: alpine:latest
        commands:
          - apk add --no-cache curl
          - |
            echo "🔍 Verifying pod status..."
            kubectl get pods -n ${VAPORA_NAMESPACE} -o wide
            echo ""
            echo "Checking pod readiness..."
            kubectl get pods -n ${VAPORA_NAMESPACE} -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.conditions[?(@.type=="Ready")].status}{"\n"}{end}'

      - name: check_services
        image: alpine:latest
        commands:
          - apk add --no-cache curl
          - |
            echo "🔍 Verifying services..."
            kubectl get services -n ${VAPORA_NAMESPACE} -o wide
            echo ""
            echo "Service endpoints:"
            kubectl get endpoints -n ${VAPORA_NAMESPACE}

      - name: collect_logs
        image: alpine:latest
        commands:
          - apk add --no-cache curl
          - |
            echo "📋 Collecting deployment logs..."
            mkdir -p ${LOGS_DIR}/kubernetes
            kubectl get events -n ${VAPORA_NAMESPACE} --sort-by='.lastTimestamp' > ${LOGS_DIR}/kubernetes/events.log 2>&1
            kubectl logs -n ${VAPORA_NAMESPACE} deployment/vapora-backend --tail=100 > ${LOGS_DIR}/kubernetes/backend.log 2>&1
            kubectl logs -n ${VAPORA_NAMESPACE} deployment/vapora-agents --tail=100 > ${LOGS_DIR}/kubernetes/agents.log 2>&1
            kubectl logs -n ${VAPORA_NAMESPACE} deployment/vapora-llm-router --tail=100 > ${LOGS_DIR}/kubernetes/llm-router.log 2>&1

      - name: annotate_deployment
        image: alpine:latest
        commands:
          - apk add --no-cache curl
          - |
            echo "📝 Annotating deployments..."
            kubectl annotate deployment vapora-backend -n ${VAPORA_NAMESPACE} \
              deployment.vapora/timestamp="$(date -u +'%Y-%m-%dT%H:%M:%SZ')" \
              deployment.vapora/commit="${CI_COMMIT_SHA:0:8}" \
              deployment.vapora/branch="${CI_COMMIT_BRANCH}" \
              --overwrite

  generate_report:
    depends_on: [verify_deployment]
    steps:
      - name: create_deployment_report
        image: alpine:latest
        commands:
          - |
            mkdir -p ${LOGS_DIR}
            cat > ${LOGS_DIR}/KUBERNETES_DEPLOYMENT_REPORT.md << 'EOF'
            # Kubernetes Deployment Report

            **Deployment Time**: $(date -u +'%Y-%m-%dT%H:%M:%SZ')
            **Commit**: ${CI_COMMIT_SHA}
            **Branch**: ${CI_COMMIT_BRANCH}
            **Namespace**: ${VAPORA_NAMESPACE}

            ## Status

            ✅ Kubernetes deployment successful

            ## Deployments

            - **vapora-backend**: Running with configured replicas
            - **vapora-agents**: Running with configured replicas
            - **vapora-llm-router**: Running with configured replicas

            ## Verification Commands

            ```bash
            # Check deployments
            kubectl get deployments -n ${VAPORA_NAMESPACE}

            # View pods
            kubectl get pods -n ${VAPORA_NAMESPACE}

            # Check logs
            kubectl logs -f deployment/vapora-backend -n ${VAPORA_NAMESPACE}

            # Port forward for local testing
            kubectl port-forward -n ${VAPORA_NAMESPACE} svc/vapora-backend 8001:8001

            # View events
            kubectl get events -n ${VAPORA_NAMESPACE} --sort-by='.lastTimestamp'

            # Check rollout status
            kubectl rollout history deployment/vapora-backend -n ${VAPORA_NAMESPACE}
            ```

            ## Next Steps

            1. Run health checks to verify all services
            2. Monitor logs for any errors
            3. Test API endpoints
            4. Set up monitoring and alerts
            5. Plan rollout to next environment

            EOF
            cat ${LOGS_DIR}/KUBERNETES_DEPLOYMENT_REPORT.md

  publish:
    depends_on: [generate_report]
    steps:
      - name: publish_results
        image: alpine:latest
        commands:
          - echo "📦 Kubernetes deployment complete"
          - echo ""
          - echo "Logs:"
          - ls -lah ${LOGS_DIR}/kubernetes/
          - echo ""
          - echo "Report:"
          - cat ${LOGS_DIR}/KUBERNETES_DEPLOYMENT_REPORT.md

      - name: notify_slack
        image: alpine:latest
        environment:
          SLACK_WEBHOOK: ${SLACK_WEBHOOK_ALERTS}
        commands:
          - |
            if [ -n "$SLACK_WEBHOOK" ]; then
              apk add --no-cache curl jq
              curl -X POST $SLACK_WEBHOOK \
                -H 'Content-Type: application/json' \
                -d '{
                  "text": "✅ VAPORA Kubernetes deployment successful!",
                  "blocks": [
                    {
                      "type": "section",
                      "text": {
                        "type": "mrkdwn",
                        "text": "✅ **VAPORA Kubernetes Deployment Successful**\n\n*Deployments Ready:*\n• backend (vapora-backend)\n• agents (vapora-agents)\n• llm-router (vapora-llm-router)"
                      }
                    },
                    {
                      "type": "context",
                      "elements": [
                        {
                          "type": "mrkdwn",
                          "text": "*Commit*: '"${CI_COMMIT_SHA:0:8}"'\n*Branch*: '"${CI_COMMIT_BRANCH}"'\n*Namespace*: '"${VAPORA_NAMESPACE}"'\n*Triggered By*: '"${CI_COMMIT_AUTHOR}"'"
                        }
                      ]
                    }
                  ]
                }'
            else
              echo "⚠️  Slack webhook not configured"
            fi
