# .gitea/workflows/ota-release.yml
# Gitea Actions — ESP32 OTA firmware build & release (bd-9kod)
#
# Triggers on signed release tags:
#   esp32-balance/vX.Y.Z  →  builds esp32s3/balance/   (ESP32-S3 Balance board)
#   esp32-io/vX.Y.Z       →  builds esp32s3-io/         (ESP32-S3 IO board)
#
# Uses the official espressif/idf Docker image for reproducible builds.
# Attaches <app>_<version>.bin + <app>_<version>.sha256 to the Gitea release.
# The ESP32 Balance OTA system fetches the .bin from the release asset URL.

name: OTA release — build & attach firmware

on:
  push:
    tags:
      - "esp32-balance/v*"
      - "esp32-io/v*"

permissions:
  contents: write

jobs:
  build-and-release:
    name: Build ${{ github.ref_name }}
    runs-on: ubuntu-latest
    container:
      image: espressif/idf:v5.2.2
      options: --user root

    steps:
      # ── 1. Checkout ───────────────────────────────────────────────────────────
      - name: Checkout
        uses: actions/checkout@v4

      # ── 2. Resolve build target from tag ─────────────────────────────────────
      # Tag format:  esp32-balance/v1.2.3  or  esp32-io/v1.2.3
      - name: Resolve project from tag
        id: proj
        shell: bash
        run: |
          TAG="${GITHUB_REF_NAME}"
          case "$TAG" in
            esp32-balance/*)
              DIR="esp32s3/balance"
              APP="esp32s3_balance"
              ;;
            esp32-io/*)
              DIR="esp32s3-io"
              APP="esp32s3_io"
              ;;
            *)
              echo "::error::Unrecognised tag prefix: ${TAG}"
              exit 1
              ;;
          esac
          VERSION="${TAG#*/}"
          echo "dir=${DIR}"         >> "$GITHUB_OUTPUT"
          echo "app=${APP}"         >> "$GITHUB_OUTPUT"
          echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
          echo "tag=${TAG}"         >> "$GITHUB_OUTPUT"
          echo "Build: ${APP} ${VERSION} from ${DIR}"

      # ── 3. Build with ESP-IDF ─────────────────────────────────────────────────
      - name: Build firmware (idf.py build)
        shell: bash
        run: |
          . "${IDF_PATH}/export.sh"
          cd "${{ steps.proj.outputs.dir }}"
          idf.py build

      # ── 4. Collect binary & generate checksum ────────────────────────────────
      - name: Collect artifacts
        id: art
        shell: bash
        run: |
          APP="${{ steps.proj.outputs.app }}"
          VER="${{ steps.proj.outputs.version }}"
          BIN_SRC="${{ steps.proj.outputs.dir }}/build/${APP}.bin"
          BIN_OUT="${APP}_${VER}.bin"
          SHA_OUT="${APP}_${VER}.sha256"

          cp "$BIN_SRC" "$BIN_OUT"
          sha256sum "$BIN_OUT" > "$SHA_OUT"

          echo "bin=${BIN_OUT}" >> "$GITHUB_OUTPUT"
          echo "sha=${SHA_OUT}" >> "$GITHUB_OUTPUT"

          echo "Binary:   ${BIN_OUT} ($(wc -c < "$BIN_OUT") bytes)"
          echo "Checksum: $(cat "$SHA_OUT")"

      # ── 5. Archive artifacts in CI workspace ─────────────────────────────────
      - name: Upload build artifacts
        uses: actions/upload-artifact@v4
        with:
          name: firmware-${{ steps.proj.outputs.app }}-${{ steps.proj.outputs.version }}
          path: |
            ${{ steps.art.outputs.bin }}
            ${{ steps.art.outputs.sha }}

      # ── 6. Create Gitea release (if needed) & upload assets ──────────────────
      # Uses GITHUB_TOKEN (auto-provided, contents:write from permissions block).
      # URL-encodes the tag to handle the slash in esp32-balance/vX.Y.Z.
      - name: Publish assets to Gitea release
        shell: bash
        env:
          GITEA_URL: https://gitea.vayrette.com
          TOKEN: ${{ secrets.GITHUB_TOKEN }}
          REPO: ${{ github.repository }}
          TAG: ${{ steps.proj.outputs.tag }}
          BIN: ${{ steps.art.outputs.bin }}
          SHA: ${{ steps.art.outputs.sha }}
        run: |
          API="${GITEA_URL}/api/v1/repos/${REPO}"

          # URL-encode the tag (slash in esp32-balance/vX.Y.Z must be escaped)
          TAG_ENC=$(python3 -c "
          import urllib.parse, sys
          print(urllib.parse.quote(sys.argv[1], safe=''))
          " "$TAG")

          # Try to fetch an existing release for this tag
          RELEASE=$(curl -sf \
            -H "Authorization: token ${TOKEN}" \
            "${API}/releases/tags/${TAG_ENC}") || true

          # If no release yet, create it
          if [ -z "$RELEASE" ]; then
            echo "Creating release for tag: ${TAG}"
            RELEASE=$(curl -sf \
              -X POST \
              -H "Authorization: token ${TOKEN}" \
              -H "Content-Type: application/json" \
              -d "$(python3 -c "
          import json, sys
          print(json.dumps({
              'tag_name': sys.argv[1],
              'name':     sys.argv[1],
              'draft':    False,
              'prerelease': False,
          }))
          " "$TAG")" \
              "${API}/releases")
          fi

          RELEASE_ID=$(echo "$RELEASE" | python3 -c "
          import sys, json; print(json.load(sys.stdin)['id'])
          ")
          echo "Release ID: ${RELEASE_ID}"

          # Upload binary and checksum
          for FILE in "$BIN" "$SHA"; do
            FNAME=$(basename "$FILE")
            echo "Uploading: ${FNAME}"
            curl -sf \
              -X POST \
              -H "Authorization: token ${TOKEN}" \
              -F "attachment=@${FILE}" \
              "${API}/releases/${RELEASE_ID}/assets?name=${FNAME}"
          done

          echo "Published: ${BIN} + ${SHA} → release ${TAG}"
