name: Test, Build, and Deploy

on:
  push:
    branches: ['**']

env:
  REGISTRY: registry.rose-ash.com:5000
  APP_DIR: /root/rose-ash
  BUILD_DIR: /root/rose-ash-ci

jobs:
  test-build-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install tools
        run: |
          apt-get update && apt-get install -y --no-install-recommends openssh-client

      - name: Set up SSH
        env:
          SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
          DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
        run: |
          mkdir -p ~/.ssh
          echo "$SSH_KEY" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa
          ssh-keyscan -H "$DEPLOY_HOST" >> ~/.ssh/known_hosts 2>/dev/null || true

      - name: Sync CI build directory
        env:
          DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
        run: |
          ssh "root@$DEPLOY_HOST" "
            BUILD=${{ env.BUILD_DIR }}
            ORIGIN=\$(git -C ${{ env.APP_DIR }} remote get-url origin)
            if [ ! -d \"\$BUILD/.git\" ]; then
              git clone \"\$ORIGIN\" \"\$BUILD\"
            fi
            cd \"\$BUILD\"
            git fetch origin
            git reset --hard origin/${{ github.ref_name }}
          "

      - name: Test SX language suite
        env:
          DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
        run: |
          ssh "root@$DEPLOY_HOST" "
            cd ${{ env.BUILD_DIR }}

            echo '=== Building SX test image ==='
            docker build \
              -f .gitea/Dockerfile.test \
              -t sx-test:${{ github.sha }} \
              .

            echo '=== Running SX tests ==='
            docker run --rm sx-test:${{ github.sha }}
          "

      - name: Build and deploy changed apps
        env:
          DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
        run: |
          ssh "root@$DEPLOY_HOST" "
            cd ${{ env.BUILD_DIR }}

            # Detect changes using push event SHAs (not local checkout state)
            BEFORE='${{ github.event.before }}'
            AFTER='${{ github.sha }}'

            REBUILD_ALL=false
            if [ -z \"\$BEFORE\" ] || [ \"\$BEFORE\" = '0000000000000000000000000000000000000000' ] || ! git cat-file -e \"\$BEFORE\" 2>/dev/null; then
              # New branch, force push, or unreachable parent — rebuild all
              REBUILD_ALL=true
            else
              CHANGED=\$(git diff --name-only \$BEFORE \$AFTER)
              if echo \"\$CHANGED\" | grep -q '^shared/'; then
                REBUILD_ALL=true
              fi
              if echo \"\$CHANGED\" | grep -q '^docker-compose.yml'; then
                REBUILD_ALL=true
              fi
            fi

            # Map compose service name to source directory
            app_dir() {
              case \"\$1\" in
                sx_docs) echo \"sx\" ;;
                *) echo \"\$1\" ;;
              esac
            }

            for app in blog market cart events federation account relations likes orders test sx_docs; do
              dir=\$(app_dir \"\$app\")
              IMAGE_EXISTS=\$(docker image ls -q ${{ env.REGISTRY }}/\$app:latest 2>/dev/null)
              if [ \"\$REBUILD_ALL\" = true ] || echo \"\$CHANGED\" | grep -q \"^\$dir/\" || [ -z \"\$IMAGE_EXISTS\" ]; then
                echo \"Building \$app...\"
                docker build \
                  --build-arg CACHEBUST=\$(date +%s) \
                  -f \$dir/Dockerfile \
                  -t ${{ env.REGISTRY }}/\$app:latest \
                  -t ${{ env.REGISTRY }}/\$app:${{ github.sha }} \
                  .
                docker push ${{ env.REGISTRY }}/\$app:latest
                docker push ${{ env.REGISTRY }}/\$app:${{ github.sha }}
              else
                echo \"Skipping \$app (no changes)\"
              fi
            done

            # Deploy swarm stacks only on main branch
            if [ '${{ github.ref_name }}' = 'main' ]; then
              source ${{ env.APP_DIR }}/.env
              docker stack deploy --resolve-image always -c docker-compose.yml rose-ash
              echo 'Waiting for swarm services to update...'
              sleep 10
              docker stack services rose-ash

              # Deploy sx-web standalone stack (sx-web.org)
              SX_REBUILT=false
              if [ \"\$REBUILD_ALL\" = true ] || echo \"\$CHANGED\" | grep -q '^sx/'; then
                SX_REBUILT=true
              fi
              if [ \"\$SX_REBUILT\" = true ]; then
                echo 'Deploying sx-web stack (sx-web.org)...'
                docker stack deploy --resolve-image always -c /root/sx-web/docker-compose.yml sx-web
                sleep 5
                docker stack services sx-web
                docker service update --force caddy_caddy 2>/dev/null || true
              fi
            else
              echo 'Skipping swarm deploy (branch: ${{ github.ref_name }})'
            fi

            # Dev stack uses working tree (bind-mounted source + auto-reload)
            cd ${{ env.APP_DIR }}
            echo 'Deploying dev stack...'
            docker compose -p rose-ash-dev -f docker-compose.yml -f docker-compose.dev.yml up -d
            echo 'Dev stack deployed'
            docker compose -p rose-ash-dev -f docker-compose.yml -f docker-compose.dev.yml ps
          "
