# VAPORA Woodpecker Pipeline - Rollback Deployment
# Safe deployment rollback with verification and pre-checks
# Triggers on: manual promotion only (safety feature)

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

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

stages:
  pre_rollback_checks:
    steps:
      - name: verify_environment
        image: alpine:latest
        commands:
          - |
            echo "🔒 Pre-Rollback Safety Checks"
            echo "---"
            mkdir -p ${LOGS_DIR}/rollback
            {
              echo "Rollback initiated at: $(date -u +'%Y-%m-%dT%H:%M:%SZ')"
              echo "Commit: ${CI_COMMIT_SHA:0:8}"
              echo "Branch: ${CI_COMMIT_BRANCH}"
              echo "Pipeline: ${CI_BUILD_LINK}"
              echo ""
              echo "⚠️  This action will rollback production systems!"
              echo "   Ensure this is intentional and approved."
            } | tee ${LOGS_DIR}/rollback/pre-rollback-snapshot.txt

  install_dependencies:
    depends_on: [pre_rollback_checks]
    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
          - yq --version

  configure_kubernetes:
    depends_on: [install_dependencies]
    steps:
      - name: setup_kubeconfig
        image: alpine:latest
        environment:
          KUBE_CONFIG_STAGING: ${KUBE_CONFIG_STAGING}
          KUBE_CONFIG_PRODUCTION: ${KUBE_CONFIG_PRODUCTION}
        commands:
          - mkdir -p ~/.kube
          - |
            if [ "${Rollback_Environment}" = "production" ]; then
              echo "$KUBE_CONFIG_PRODUCTION" | base64 -d > ~/.kube/config
              echo "✓ Production kubeconfig configured"
            else
              echo "$KUBE_CONFIG_STAGING" | base64 -d > ~/.kube/config
              echo "✓ Staging kubeconfig configured"
            fi
          - chmod 600 ~/.kube/config
          - kubectl cluster-info
          - kubectl get nodes

  store_deployment_history:
    depends_on: [configure_kubernetes]
    steps:
      - name: snapshot_current_state
        image: alpine:latest
        commands:
          - apk add --no-cache curl
          - |
            echo "📸 Storing current deployment history..."
            mkdir -p ${LOGS_DIR}/rollback
            {
              echo "=== Current Deployment State ===" | tee ${LOGS_DIR}/rollback/pre-rollback-status.txt
              echo ""
              echo "Deployments:"
              kubectl get deployments -n ${VAPORA_NAMESPACE} -o yaml | tee -a ${LOGS_DIR}/rollback/pre-rollback-status.txt
              echo ""
              echo "Rollout History:"
              for deployment in vapora-backend vapora-agents vapora-llm-router; do
                echo "--- $deployment ---" | tee -a ${LOGS_DIR}/rollback/pre-rollback-status.txt
                kubectl rollout history deployment/$deployment -n ${VAPORA_NAMESPACE} 2>&1 | tee -a ${LOGS_DIR}/rollback/pre-rollback-status.txt
              done
            }

  kubernetes_rollback:
    depends_on: [store_deployment_history]
    steps:
      - name: perform_rollback
        image: rust:latest
        environment:
          RUST_LOG: warn
        commands:
          - apt-get update && apt-get install -y curl jq
          - |
            echo "🔙 Performing Kubernetes Rollback..."
            mkdir -p ${LOGS_DIR}/rollback
            cd provisioning
            nu scripts/rollback.nu \
              --target kubernetes \
              --deployment "${Rollback_Deployment:-all}" \
              --revision ${Rollback_Revision:-0} \
              2>&1 | tee ../${LOGS_DIR}/rollback/rollback-output.log

      - name: verify_rollback
        image: alpine:latest
        commands:
          - apk add --no-cache curl
          - |
            echo "✓ Verifying rollback status..."
            {
              echo "=== Post-Rollback Deployment State ===" | tee ${LOGS_DIR}/rollback/post-rollback-status.txt
              echo ""
              echo "Deployments:"
              kubectl get deployments -n ${VAPORA_NAMESPACE} -o wide | tee -a ${LOGS_DIR}/rollback/post-rollback-status.txt
              echo ""
              echo "Rollout Status:"
              for deployment in vapora-backend vapora-agents vapora-llm-router; do
                echo "--- $deployment ---" | tee -a ${LOGS_DIR}/rollback/post-rollback-status.txt
                kubectl rollout status deployment/$deployment -n ${VAPORA_NAMESPACE} --timeout=5m 2>&1 | tee -a ${LOGS_DIR}/rollback/post-rollback-status.txt
              done
            }

      - name: check_pod_health
        image: alpine:latest
        commands:
          - apk add --no-cache curl
          - |
            echo "Pod Status After Rollback:" | tee -a ${LOGS_DIR}/rollback/post-rollback-status.txt
            kubectl get pods -n ${VAPORA_NAMESPACE} -o wide | tee -a ${LOGS_DIR}/rollback/post-rollback-status.txt
            echo "" | tee -a ${LOGS_DIR}/rollback/post-rollback-status.txt
            echo "Recent Events:" | tee -a ${LOGS_DIR}/rollback/post-rollback-status.txt
            kubectl get events -n ${VAPORA_NAMESPACE} --sort-by='.lastTimestamp' | tail -20 | tee -a ${LOGS_DIR}/rollback/post-rollback-status.txt

  docker_rollback_guide:
    depends_on: [store_deployment_history]
    steps:
      - name: generate_docker_guide
        image: alpine:latest
        commands:
          - |
            echo "📝 Generating Docker rollback guide..."
            mkdir -p ${LOGS_DIR}/rollback
            cat > ${LOGS_DIR}/rollback/DOCKER_ROLLBACK_GUIDE.md << 'EOF'
            # Docker Rollback Guide

            Docker Compose rollback requires manual steps:

            ## Option 1: Revert to previous compose file

            ```bash
            cd deploy/docker
            docker compose down
            git checkout HEAD~1 docker-compose.yml
            docker compose up -d
            ```

            ## Option 2: Stop and restart with older images

            ```bash
            docker compose -f docker-compose.yml.backup up -d
            ```

            ## Option 3: Remove containers and redeploy from previous artifacts

            ```bash
            docker compose down
            docker system prune -f
            docker compose up -d
            ```

            ## Verification

            After rollback, verify services are running:

            ```bash
            docker compose ps
            docker compose logs -f backend
            curl http://localhost:8001/health
            ```

            ## Checking Compose File Backups

            ```bash
            find . -name "docker-compose*.yml*" -type f | sort
            ```

            ## Restoring from Backup

            ```bash
            # If you have a timestamped backup
            cp docker-compose.yml.$(date +%s) docker-compose.yml
            docker compose up -d
            ```

            EOF
            cat ${LOGS_DIR}/rollback/DOCKER_ROLLBACK_GUIDE.md

      - name: store_docker_state
        image: alpine:latest
        commands:
          - |
            echo "📋 Storing Docker Compose state..."
            mkdir -p ${LOGS_DIR}/rollback
            if [ -f "deploy/docker/docker-compose.yml" ]; then
              cp deploy/docker/docker-compose.yml ${LOGS_DIR}/rollback/current-docker-compose.yml
              echo "✓ Current docker-compose.yml backed up"
            fi

            echo "Looking for available backups..."
            find . -name "docker-compose*.yml*" -type f 2>/dev/null | head -20 | tee ${LOGS_DIR}/rollback/available-backups.txt

  post_rollback_verification:
    depends_on: [kubernetes_rollback, docker_rollback_guide]
    steps:
      - name: generate_rollback_report
        image: alpine:latest
        commands:
          - |
            mkdir -p ${LOGS_DIR}/rollback
            cat > ${LOGS_DIR}/rollback/ROLLBACK_REPORT.md << 'EOF'
            # Rollback Execution Report

            **Rollback Time**: $(date -u +'%Y-%m-%dT%H:%M:%SZ')
            **Target**: ${Rollback_Target:-kubernetes}
            **Environment**: ${Rollback_Environment:-staging}
            **Deployment**: ${Rollback_Deployment:-all}
            **Revision**: ${Rollback_Revision:-0 (previous)}
            **Pipeline**: ${CI_BUILD_LINK}

            ## Status

            - **Pre-rollback Checks**: ✅ Passed
            - **Rollback Execution**: In Progress
            - **Post-rollback Verification**: Pending

            ## Artifacts

            Check the following for detailed information:

            - `pre-rollback-snapshot.txt` - Initial state snapshot
            - `pre-rollback-status.txt` - Pre-rollback deployments
            - `post-rollback-status.txt` - Post-rollback status
            - `rollback-output.log` - Rollback script output
            - `DOCKER_ROLLBACK_GUIDE.md` - Docker rollback instructions (if applicable)

            ## Next Steps

            1. Verify all services are running
            2. Check application logs for errors
            3. Run health checks
            4. Monitor metrics and alerts
            5. Investigate root cause of previous deployment failure
            6. Plan corrected deployment

            ## Rollback Verification Commands

            ### For Kubernetes

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

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

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

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

            ### For Docker

            ```bash
            # Check container status
            docker compose ps

            # View logs
            docker compose logs -f

            # Check service health
            curl http://localhost:8001/health
            ```

            EOF
            cat ${LOGS_DIR}/rollback/ROLLBACK_REPORT.md

  publish:
    depends_on: [post_rollback_verification]
    steps:
      - name: publish_rollback_artifacts
        image: alpine:latest
        commands:
          - echo "📦 Rollback artifacts published"
          - echo ""
          - ls -lah ${LOGS_DIR}/rollback/
          - echo ""
          - du -sh ${LOGS_DIR}/rollback/

      - 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 Rollback Executed",
                  "blocks": [
                    {
                      "type": "section",
                      "text": {
                        "type": "mrkdwn",
                        "text": "🔙 **VAPORA Rollback Executed**\n\n*Rollback Details:*\n• Target: ${Rollback_Target:-kubernetes}\n• Environment: ${Rollback_Environment:-staging}\n• Deployment: ${Rollback_Deployment:-all}"
                      }
                    },
                    {
                      "type": "section",
                      "text": {
                        "type": "mrkdwn",
                        "text": "*⚠️  Action Required:*\n1. Verify service health\n2. Review application logs\n3. Investigate root cause\n4. Plan corrected deployment"
                      }
                    },
                    {
                      "type": "context",
                      "elements": [
                        {
                          "type": "mrkdwn",
                          "text": "*Reports*: Check rollback artifacts in logs\n*Commit*: '"${CI_COMMIT_SHA:0:8}"'\n*Branch*: '"${CI_COMMIT_BRANCH}"'"
                        }
                      ]
                    }
                  ]
                }'
            else
              echo "⚠️  Slack webhook not configured"
            fi
