name: Build and Deploy

on:
  push:
    branches:
      - main
      - master

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2
        with:
          config-inline: |
            [registry."docker.io"]
              mirrors = ["https://docker.m.daocloud.io", "https://docker.1panel.live", "https://hub.rat.dev"]

      - name: Login to Huawei Cloud SWR
        uses: docker/login-action@v2
        with:
          registry: ${{ secrets.SWR_SERVER }}
          username: ${{ secrets.SWR_USERNAME }}
          password: ${{ secrets.SWR_PASSWORD }}

      - name: Build and Push Backend
        id: build_backend
        run: |
          set -o pipefail
          docker buildx build \
            --push \
            --provenance=false \
            --tag ${{ secrets.SWR_SERVER }}/${{ secrets.SWR_ORG }}/video-backend:latest \
            ./backend 2>&1 | tee /tmp/build.log

      - name: Build and Push Web
        id: build_web
        run: |
          set -o pipefail
          docker buildx build \
            --push \
            --provenance=false \
            --tag ${{ secrets.SWR_SERVER }}/${{ secrets.SWR_ORG }}/video-web:latest \
            ./web 2>&1 | tee -a /tmp/build.log

      - name: Setup SSH
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.K3S_SSH_KEY }}" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa
          ssh-keyscan -H ${{ secrets.K3S_HOST }} >> ~/.ssh/known_hosts 2>/dev/null

      - name: Deploy to K3s via SSH
        id: deploy
        run: |
          SWR_IMAGE="${{ secrets.SWR_SERVER }}/${{ secrets.SWR_ORG }}"

          # Replace image placeholders in yaml files
          sed -i "s|\${CI_REGISTRY_IMAGE}/video-backend:latest|${SWR_IMAGE}/video-backend:latest|g" k8s/backend-deployment.yaml
          sed -i "s|\${CI_REGISTRY_IMAGE}/video-web:latest|${SWR_IMAGE}/video-web:latest|g" k8s/web-deployment.yaml

          # Copy k8s manifests to server
          scp -o StrictHostKeyChecking=no k8s/backend-deployment.yaml k8s/web-deployment.yaml k8s/ingress.yaml root@${{ secrets.K3S_HOST }}:/tmp/

          # Create/update secrets and apply manifests on server
          set -o pipefail
          ssh -o StrictHostKeyChecking=no root@${{ secrets.K3S_HOST }} << ENDSSH
            export KUBECONFIG=/etc/rancher/k3s/k3s.yaml

            kubectl create secret generic video-backend-secrets \
              --from-literal=ARK_API_KEY='${{ secrets.ARK_API_KEY }}' \
              --from-literal=TOS_ACCESS_KEY='${{ secrets.TOS_ACCESS_KEY }}' \
              --from-literal=TOS_SECRET_KEY='${{ secrets.TOS_SECRET_KEY }}' \
              --from-literal=DJANGO_SECRET_KEY='${{ secrets.DJANGO_SECRET_KEY }}' \
              --from-literal=DB_HOST='${{ secrets.DB_HOST }}' \
              --from-literal=DB_USER='${{ secrets.DB_USER }}' \
              --from-literal=DB_PASSWORD='${{ secrets.DB_PASSWORD }}' \
              --from-literal=ALIYUN_SMS_ACCESS_KEY='${{ secrets.ALIYUN_SMS_ACCESS_KEY }}' \
              --from-literal=ALIYUN_SMS_ACCESS_SECRET='${{ secrets.ALIYUN_SMS_ACCESS_SECRET }}' \
              --dry-run=client -o yaml | kubectl apply -f -

            kubectl apply -f /tmp/backend-deployment.yaml
            kubectl apply -f /tmp/web-deployment.yaml
            kubectl apply -f /tmp/ingress.yaml
            kubectl rollout restart deployment/video-backend
            kubectl rollout restart deployment/video-web

            rm -f /tmp/backend-deployment.yaml /tmp/web-deployment.yaml /tmp/ingress.yaml
          ENDSSH

      # ===== Log Center: failure reporting =====
      - name: Report failure to Log Center
        if: failure()
        run: |
          BUILD_LOG=""
          DEPLOY_LOG=""
          FAILED_STEP="unknown"

          if [[ "${{ steps.build_backend.outcome }}" == "failure" || "${{ steps.build_web.outcome }}" == "failure" ]]; then
            FAILED_STEP="build"
            if [ -f /tmp/build.log ]; then
              BUILD_LOG=$(tail -50 /tmp/build.log | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g')
            fi
          elif [[ "${{ steps.deploy.outcome }}" == "failure" ]]; then
            FAILED_STEP="deploy"
            if [ -f /tmp/deploy.log ]; then
              DEPLOY_LOG=$(tail -50 /tmp/deploy.log | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g')
            fi
          fi

          ERROR_LOG="${BUILD_LOG}${DEPLOY_LOG}"
          if [ -z "$ERROR_LOG" ]; then
            ERROR_LOG="No captured output. Check Gitea Actions UI for details."
          fi

          if [[ "$FAILED_STEP" == "deploy" ]]; then
            SOURCE="deployment"
            ERROR_TYPE="DeployError"
          else
            SOURCE="cicd"
            ERROR_TYPE="DockerBuildError"
          fi

          curl -s -X POST "https://qiyuan-log-center-api.airlabs.art/api/v1/logs/report" \
            -H "Content-Type: application/json" \
            -d "{
              \"project_id\": \"video_backend\",
              \"environment\": \"${{ github.ref_name }}\",
              \"level\": \"ERROR\",
              \"source\": \"${SOURCE}\",
              \"commit_hash\": \"${{ github.sha }}\",
              \"repo_url\": \"https://gitea.airlabs.art/zyc/video-shuoshan.git\",
              \"error\": {
                \"type\": \"${ERROR_TYPE}\",
                \"message\": \"[${FAILED_STEP}] Build and Deploy failed on branch ${{ github.ref_name }}\",
                \"stack_trace\": [\"${ERROR_LOG}\"]
              },
              \"context\": {
                \"job_name\": \"build-and-deploy\",
                \"step_name\": \"${FAILED_STEP}\",
                \"workflow\": \"${{ github.workflow }}\",
                \"run_id\": \"${{ github.run_number }}\",
                \"branch\": \"${{ github.ref_name }}\",
                \"actor\": \"${{ github.actor }}\",
                \"commit\": \"${{ github.sha }}\",
                \"run_url\": \"https://gitea.airlabs.art/${{ github.repository }}/actions/runs/${{ github.run_number }}\"
              }
            }" || true
