# Build + push compliance service images to registry.meghsakha.com
# and trigger orca redeploy after CI passes on main.
#
# This workflow is gated on the CI workflow completing successfully.
# It does not run independently — if CI fails, builds + deploy are skipped.
# Per-service builds are gated on detect-changes so only services with
# modified files are rebuilt; trigger-orca runs only if at least one build
# succeeded and none failed.
#
# Requires Gitea Actions secrets:
#   REGISTRY_USERNAME / REGISTRY_PASSWORD  — registry.meghsakha.com credentials
#   ORCA_WEBHOOK_SECRET                    — must match webhooks.json on orca master

name: Build + Deploy

on:
  workflow_run:
    workflows: ["CI"]
    types: [completed]
    branches: [main]

jobs:
  # ── gate: only proceed if CI succeeded ────────────────────────────────────
  ci-passed:
    runs-on: docker
    container: alpine:3.20
    if: github.event.workflow_run.conclusion == 'success'
    steps:
      - name: CI passed, proceeding with build + deploy
        run: echo "CI run ${{ github.event.workflow_run.id }} succeeded on ${{ github.event.workflow_run.head_branch }} @ ${{ github.event.workflow_run.head_sha }}"

  # ── detect which services changed since the last successful build ────────
  # Diff base = the last-build/main git tag, set by mark-last-build at the
  # end of every successful run. Works across squash merges, multi-commit
  # raw pushes, and force pushes (force pushes leave a stale tag → diff
  # shows symmetric differences → safe over-rebuild). If the tag doesn't
  # exist yet, scripts/detect-changes.sh falls back to rebuilding all.
  detect-changes:
    runs-on: docker
    container: alpine:3.20
    needs: ci-passed
    outputs:
      admin: ${{ steps.diff.outputs.admin }}
      backend: ${{ steps.diff.outputs.backend }}
      sdk: ${{ steps.diff.outputs.sdk }}
      portal: ${{ steps.diff.outputs.portal }}
      tts: ${{ steps.diff.outputs.tts }}
      crawler: ${{ steps.diff.outputs.crawler }}
      dsms_gateway: ${{ steps.diff.outputs.dsms_gateway }}
      dsms_node: ${{ steps.diff.outputs.dsms_node }}
    steps:
      - name: Checkout
        run: |
          apk add --no-cache git bash
          git clone --depth 200 --branch ${GITHUB_REF_NAME} ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git .
          git fetch --tags origin || true
      - name: Resolve base SHA from last-build/main tag
        run: |
          BASE=$(git rev-parse --verify refs/tags/last-build/main 2>/dev/null || true)
          echo "Base SHA: ${BASE:-<none, will rebuild all>}"
          # Deepen if base isn't yet in the shallow clone.
          if [ -n "$BASE" ] && ! git rev-parse --verify "${BASE}^{commit}" >/dev/null 2>&1; then
            git fetch --unshallow origin 2>/dev/null \
              || git fetch --depth=10000 origin 2>/dev/null \
              || true
          fi
          echo "BASE_SHA=${BASE}" >> "$GITHUB_ENV"
      - name: Detect changes
        id: diff
        run: bash scripts/detect-changes.sh

  # ── per-service builds run in parallel (only changed services) ────────────

  build-admin-compliance:
    runs-on: docker
    container: docker:27-cli
    needs: detect-changes
    if: needs.detect-changes.outputs.admin == 'true'
    steps:
      - name: Checkout
        run: |
          apk add --no-cache git
          git clone --depth 1 --branch ${GITHUB_REF_NAME} ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git .
      - name: Login
        env:
          REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
          REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
        run: echo "$REGISTRY_PASSWORD" | docker login registry.meghsakha.com -u "$REGISTRY_USERNAME" --password-stdin
      - name: Build + push
        run: |
          SHORT_SHA=$(git rev-parse --short HEAD)
          docker build \
            -t registry.meghsakha.com/breakpilot/compliance-admin:latest \
            -t registry.meghsakha.com/breakpilot/compliance-admin:${SHORT_SHA} \
            admin-compliance/
          docker push registry.meghsakha.com/breakpilot/compliance-admin:latest
          docker push registry.meghsakha.com/breakpilot/compliance-admin:${SHORT_SHA}

  build-backend-compliance:
    runs-on: docker
    container: docker:27-cli
    needs: detect-changes
    if: needs.detect-changes.outputs.backend == 'true'
    steps:
      - name: Checkout
        run: |
          apk add --no-cache git
          git clone --depth 1 --branch ${GITHUB_REF_NAME} ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git .
      - name: Login
        env:
          REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
          REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
        run: echo "$REGISTRY_PASSWORD" | docker login registry.meghsakha.com -u "$REGISTRY_USERNAME" --password-stdin
      - name: Build + push
        run: |
          SHORT_SHA=$(git rev-parse --short HEAD)
          docker build \
            -t registry.meghsakha.com/breakpilot/compliance-backend:latest \
            -t registry.meghsakha.com/breakpilot/compliance-backend:${SHORT_SHA} \
            backend-compliance/
          docker push registry.meghsakha.com/breakpilot/compliance-backend:latest
          docker push registry.meghsakha.com/breakpilot/compliance-backend:${SHORT_SHA}

  build-ai-sdk:
    runs-on: docker
    container: docker:27-cli
    needs: detect-changes
    if: needs.detect-changes.outputs.sdk == 'true'
    steps:
      - name: Checkout
        run: |
          apk add --no-cache git
          git clone --depth 1 --branch ${GITHUB_REF_NAME} ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git .
      - name: Login
        env:
          REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
          REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
        run: echo "$REGISTRY_PASSWORD" | docker login registry.meghsakha.com -u "$REGISTRY_USERNAME" --password-stdin
      - name: Build + push
        run: |
          SHORT_SHA=$(git rev-parse --short HEAD)
          docker build \
            -t registry.meghsakha.com/breakpilot/compliance-sdk:latest \
            -t registry.meghsakha.com/breakpilot/compliance-sdk:${SHORT_SHA} \
            ai-compliance-sdk/
          docker push registry.meghsakha.com/breakpilot/compliance-sdk:latest
          docker push registry.meghsakha.com/breakpilot/compliance-sdk:${SHORT_SHA}

  build-developer-portal:
    runs-on: docker
    container: docker:27-cli
    needs: detect-changes
    if: needs.detect-changes.outputs.portal == 'true'
    steps:
      - name: Checkout
        run: |
          apk add --no-cache git
          git clone --depth 1 --branch ${GITHUB_REF_NAME} ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git .
      - name: Login
        env:
          REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
          REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
        run: echo "$REGISTRY_PASSWORD" | docker login registry.meghsakha.com -u "$REGISTRY_USERNAME" --password-stdin
      - name: Build + push
        run: |
          SHORT_SHA=$(git rev-parse --short HEAD)
          docker build \
            -t registry.meghsakha.com/breakpilot/compliance-portal:latest \
            -t registry.meghsakha.com/breakpilot/compliance-portal:${SHORT_SHA} \
            developer-portal/
          docker push registry.meghsakha.com/breakpilot/compliance-portal:latest
          docker push registry.meghsakha.com/breakpilot/compliance-portal:${SHORT_SHA}

  build-tts:
    runs-on: docker
    container: docker:27-cli
    needs: detect-changes
    if: needs.detect-changes.outputs.tts == 'true'
    steps:
      - name: Checkout
        run: |
          apk add --no-cache git
          git clone --depth 1 --branch ${GITHUB_REF_NAME} ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git .
      - name: Login
        env:
          REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
          REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
        run: echo "$REGISTRY_PASSWORD" | docker login registry.meghsakha.com -u "$REGISTRY_USERNAME" --password-stdin
      - name: Build + push
        run: |
          SHORT_SHA=$(git rev-parse --short HEAD)
          docker build \
            -t registry.meghsakha.com/breakpilot/compliance-tts:latest \
            -t registry.meghsakha.com/breakpilot/compliance-tts:${SHORT_SHA} \
            compliance-tts-service/
          docker push registry.meghsakha.com/breakpilot/compliance-tts:latest
          docker push registry.meghsakha.com/breakpilot/compliance-tts:${SHORT_SHA}

  build-document-crawler:
    runs-on: docker
    container: docker:27-cli
    needs: detect-changes
    if: needs.detect-changes.outputs.crawler == 'true'
    steps:
      - name: Checkout
        run: |
          apk add --no-cache git
          git clone --depth 1 --branch ${GITHUB_REF_NAME} ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git .
      - name: Login
        env:
          REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
          REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
        run: echo "$REGISTRY_PASSWORD" | docker login registry.meghsakha.com -u "$REGISTRY_USERNAME" --password-stdin
      - name: Build + push
        run: |
          SHORT_SHA=$(git rev-parse --short HEAD)
          docker build \
            -t registry.meghsakha.com/breakpilot/compliance-crawler:latest \
            -t registry.meghsakha.com/breakpilot/compliance-crawler:${SHORT_SHA} \
            document-crawler/
          docker push registry.meghsakha.com/breakpilot/compliance-crawler:latest
          docker push registry.meghsakha.com/breakpilot/compliance-crawler:${SHORT_SHA}

  build-dsms-gateway:
    runs-on: docker
    container: docker:27-cli
    needs: detect-changes
    if: needs.detect-changes.outputs.dsms_gateway == 'true'
    steps:
      - name: Checkout
        run: |
          apk add --no-cache git
          git clone --depth 1 --branch ${GITHUB_REF_NAME} ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git .
      - name: Login
        env:
          REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
          REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
        run: echo "$REGISTRY_PASSWORD" | docker login registry.meghsakha.com -u "$REGISTRY_USERNAME" --password-stdin
      - name: Build + push
        run: |
          SHORT_SHA=$(git rev-parse --short HEAD)
          docker build \
            -t registry.meghsakha.com/breakpilot/compliance-dsms-gateway:latest \
            -t registry.meghsakha.com/breakpilot/compliance-dsms-gateway:${SHORT_SHA} \
            dsms-gateway/
          docker push registry.meghsakha.com/breakpilot/compliance-dsms-gateway:latest
          docker push registry.meghsakha.com/breakpilot/compliance-dsms-gateway:${SHORT_SHA}

  build-dsms-node:
    runs-on: docker
    container: docker:27-cli
    needs: detect-changes
    if: needs.detect-changes.outputs.dsms_node == 'true'
    steps:
      - name: Checkout
        run: |
          apk add --no-cache git
          git clone --depth 1 --branch ${GITHUB_REF_NAME} ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git .
      - name: Login
        env:
          REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
          REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
        run: echo "$REGISTRY_PASSWORD" | docker login registry.meghsakha.com -u "$REGISTRY_USERNAME" --password-stdin
      - name: Build + push
        run: |
          SHORT_SHA=$(git rev-parse --short HEAD)
          docker build --platform linux/amd64 \
            -t registry.meghsakha.com/breakpilot/compliance-dsms-node:latest \
            -t registry.meghsakha.com/breakpilot/compliance-dsms-node:${SHORT_SHA} \
            dsms-node/
          docker push registry.meghsakha.com/breakpilot/compliance-dsms-node:latest
          docker push registry.meghsakha.com/breakpilot/compliance-dsms-node:${SHORT_SHA}

  # ── advance the last-build/main tag — the diff base for future runs ──────
  # Runs when no build failed. Covers two cases:
  #   - at least one service was rebuilt → mark this SHA as the new baseline
  #   - all services were skipped (nothing changed) → still advance the tag
  #     so we don't keep re-evaluating the same skipped commits forever
  # Skips if any build failed → tag stays put → next push retries those
  # services from the previous known-good base.
  mark-last-build:
    runs-on: docker
    container: alpine:3.20
    needs:
      - build-admin-compliance
      - build-backend-compliance
      - build-ai-sdk
      - build-developer-portal
      - build-tts
      - build-document-crawler
      - build-dsms-gateway
      - build-dsms-node
    if: |
      always() &&
      !contains(needs.*.result, 'failure') &&
      !contains(needs.*.result, 'cancelled')
    env:
      GITEA_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
    steps:
      - name: Checkout
        run: |
          apk add --no-cache git
          git clone --depth 1 --branch ${GITHUB_REF_NAME} ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git .
      - name: Force-push last-build/main tag
        run: |
          set -e
          SHA="${HEAD_SHA:-$(git rev-parse HEAD)}"
          echo "Advancing last-build/main → ${SHA}"
          git tag -f last-build/main "$SHA"
          # Encode token into the push URL (no on-disk credential persistence).
          PUSH_URL="${GITHUB_SERVER_URL/https:\/\//https:\/\/x-access-token:${GITEA_TOKEN}@}/${GITHUB_REPOSITORY}.git"
          git push --force "$PUSH_URL" "refs/tags/last-build/main"
          echo "Tag last-build/main now at ${SHA}"

  # ── orca redeploy — runs if at least one build was triggered AND green ────
  # Per-job `result == 'success'` is true only when the job actually ran and
  # passed; skipped/failed/cancelled jobs return their own status string and
  # fail the OR. This avoids Gitea's quirky evaluation of `contains(needs.*
  # .result, 'success')` when most upstreams are skipped (root cause of
  # trigger-orca being skipped on single-service changes).
  # `always()` is required so the job is evaluated when upstreams skip.

  trigger-orca:
    runs-on: docker
    container: docker:27-cli
    needs:
      - build-admin-compliance
      - build-backend-compliance
      - build-ai-sdk
      - build-developer-portal
      - build-tts
      - build-document-crawler
      - build-dsms-gateway
      - build-dsms-node
    if: |
      always() &&
      (
        needs.build-admin-compliance.result == 'success' ||
        needs.build-backend-compliance.result == 'success' ||
        needs.build-ai-sdk.result == 'success' ||
        needs.build-developer-portal.result == 'success' ||
        needs.build-tts.result == 'success' ||
        needs.build-document-crawler.result == 'success' ||
        needs.build-dsms-gateway.result == 'success' ||
        needs.build-dsms-node.result == 'success'
      )
    steps:
      - name: Checkout (for SHA)
        run: |
          apk add --no-cache git curl openssl
          git clone --depth 1 --branch ${GITHUB_REF_NAME} ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git .
      - name: Trigger orca redeploy
        env:
          ORCA_WEBHOOK_SECRET: ${{ secrets.ORCA_WEBHOOK_SECRET }}
          ORCA_WEBHOOK_URL: http://46.225.100.82:6880/api/v1/webhooks/github
        run: |
          SHA=$(git rev-parse HEAD)
          PAYLOAD="{\"ref\":\"refs/heads/main\",\"repository\":{\"full_name\":\"${GITHUB_REPOSITORY}\"},\"head_commit\":{\"id\":\"$SHA\",\"message\":\"ci: compliance images built\"}}"
          SIG=$(printf '%s' "$PAYLOAD" | openssl dgst -sha256 -hmac "$ORCA_WEBHOOK_SECRET" -r | awk '{print $1}')
          curl -sSf -k \
            -X POST \
            -H "Content-Type: application/json" \
            -H "X-GitHub-Event: push" \
            -H "X-Hub-Signature-256: sha256=$SIG" \
            -d "$PAYLOAD" \
            "$ORCA_WEBHOOK_URL" \
            || { echo "Orca redeploy failed"; exit 1; }
          echo "Orca redeploy triggered for compliance services"
