name: Release Tool

on:
  push:
    tags:
      - "v*"

jobs:
  release:
    runs-on: self-hosted
    env:
      CHECKOUT_PATH: ${{ vars.SOW_TOOLS_CHECKOUT_PATH }}

    steps:
      - name: Sync tools checkout to tag
        env:
          TAG_NAME: ${{ github.ref_name }}
        run: |
          set -euo pipefail
          CHECKOUT_PATH="${CHECKOUT_PATH:-/home/ubuntu/tools-checkout}"
          cd "${CHECKOUT_PATH}"
          git fetch origin --prune --tags
          git reset --hard "${TAG_NAME}"
          git clean -fd

      - name: Build sow-toolkit binaries
        run: |
          set -euo pipefail
          CHECKOUT_PATH="${CHECKOUT_PATH:-/home/ubuntu/tools-checkout}"
          cd "${CHECKOUT_PATH}"
          mkdir -p tools .cache/go-build
          GOCACHE="${PWD}/.cache/go-build" go build -o ./tools/sow-toolkit ./cmd/nwn-tool
          GOOS=windows GOARCH=amd64 GOCACHE="${PWD}/.cache/go-build" go build -o ./tools/sow-toolkit.exe ./cmd/nwn-tool

      - name: Pack release bundles
        id: pack
        env:
          TAG_NAME: ${{ github.ref_name }}
        run: |
          set -euo pipefail
          CHECKOUT_PATH="${CHECKOUT_PATH:-/home/ubuntu/tools-checkout}"
          cd "${CHECKOUT_PATH}"
          linux_binary="tools/sow-toolkit"
          windows_binary="tools/sow-toolkit.exe"
          if [[ ! -x "${linux_binary}" ]]; then
            echo "Missing built tool: ${linux_binary}"
            exit 1
          fi
          if [[ ! -f "${windows_binary}" ]]; then
            echo "Missing built tool: ${windows_binary}"
            exit 1
          fi
          linux_archive="/tmp/sow-toolkit-linux-amd64-${TAG_NAME}.tar.gz"
          windows_archive="/tmp/sow-toolkit-windows-amd64-${TAG_NAME}.exe"
          tar -czf "${linux_archive}" -C tools sow-toolkit
          cp "${windows_binary}" "${windows_archive}"
          echo "linux_archive=${linux_archive}" >> "$GITHUB_OUTPUT"
          echo "linux_asset_name=sow-toolkit-linux-amd64.tar.gz" >> "$GITHUB_OUTPUT"
          echo "windows_archive=${windows_archive}" >> "$GITHUB_OUTPUT"
          echo "windows_asset_name=sow-toolkit-windows-amd64.exe" >> "$GITHUB_OUTPUT"
          echo "tag=${TAG_NAME}" >> "$GITHUB_OUTPUT"

      - name: Create release and upload artifacts
        env:
          GITEA_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GITEA_SERVER_URL: ${{ github.server_url }}
          GITEA_REPO: ${{ github.repository }}
          LINUX_ARCHIVE: ${{ steps.pack.outputs.linux_archive }}
          LINUX_ASSET_NAME: ${{ steps.pack.outputs.linux_asset_name }}
          WINDOWS_ARCHIVE: ${{ steps.pack.outputs.windows_archive }}
          WINDOWS_ASSET_NAME: ${{ steps.pack.outputs.windows_asset_name }}
          TAG_NAME: ${{ steps.pack.outputs.tag }}
        run: |
          set -euo pipefail
          API="${GITEA_SERVER_URL%/}/api/v1"
          OWNER="${GITEA_REPO%%/*}"
          NAME="${GITEA_REPO#*/}"
          AUTH=(-H "Authorization: token ${GITEA_API_TOKEN}" -H "Accept: application/json")
          RESP_FILE=/tmp/gitea-release.json

          CODE=$(curl -sS -o "${RESP_FILE}" -w "%{http_code}" "${AUTH[@]}" \
            "${API}/repos/${OWNER}/${NAME}/releases/tags/${TAG_NAME}")

          if [[ "${CODE}" == "200" ]]; then
            RELEASE_ID=$(jq -r '.id' "${RESP_FILE}")
          else
            BODY=$(jq -n --arg t "${TAG_NAME}" \
              '{tag_name: $t, name: $t, body: "sow-toolkit binary release built by Gitea Actions."}')
            CODE=$(curl -sS -o "${RESP_FILE}" -w "%{http_code}" "${AUTH[@]}" \
              -X POST -H "Content-Type: application/json" \
              -d "${BODY}" \
              "${API}/repos/${OWNER}/${NAME}/releases")
            if [[ "${CODE}" != "201" && "${CODE}" != "200" ]]; then
              echo "Create release failed (HTTP ${CODE}):"
              cat "${RESP_FILE}"
              exit 1
            fi
            RELEASE_ID=$(jq -r '.id' "${RESP_FILE}")
          fi

          for name in "${LINUX_ASSET_NAME}" "${WINDOWS_ASSET_NAME}"; do
            ASSET_ID=$(jq -r --arg name "${name}" '.assets[]? | select(.name == $name) | .id' "${RESP_FILE}" | head -n1)
            if [[ -n "${ASSET_ID}" ]]; then
              curl -sS -f "${AUTH[@]}" -X DELETE \
                "${API}/repos/${OWNER}/${NAME}/releases/${RELEASE_ID}/assets/${ASSET_ID}"
            fi
          done

          curl -sS -f "${AUTH[@]}" -X POST \
            -F "attachment=@${LINUX_ARCHIVE}" \
            "${API}/repos/${OWNER}/${NAME}/releases/${RELEASE_ID}/assets?name=${LINUX_ASSET_NAME}"

          curl -sS -f "${AUTH[@]}" -X POST \
            -F "attachment=@${WINDOWS_ARCHIVE}" \
            "${API}/repos/${OWNER}/${NAME}/releases/${RELEASE_ID}/assets?name=${WINDOWS_ASSET_NAME}"

      - name: Cleanup temporary files
        if: always()
        env:
          TAG_NAME: ${{ github.ref_name }}
        run: |
          rm -f \
            "/tmp/sow-toolkit-linux-amd64-${TAG_NAME}.tar.gz" \
            "/tmp/sow-toolkit-windows-amd64-${TAG_NAME}.exe" \
            /tmp/gitea-release.json

      - name: Prune old releases (keep latest 1)
        env:
          GITEA_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GITEA_SERVER_URL: ${{ github.server_url }}
          GITEA_REPO: ${{ github.repository }}
        run: |
          set -euo pipefail
          API="${GITEA_SERVER_URL%/}/api/v1"
          OWNER="${GITEA_REPO%%/*}"
          NAME="${GITEA_REPO#*/}"
          AUTH=(-H "Authorization: token ${GITEA_API_TOKEN}" -H "Accept: application/json")
          curl -sS "${AUTH[@]}" \
            "${API}/repos/${OWNER}/${NAME}/releases?limit=50&page=1" \
            -o /tmp/all-releases.json
          jq -r '.[1:][].id' /tmp/all-releases.json | while read -r rid; do
            [[ -n "${rid}" ]] || continue
            curl -sS -f "${AUTH[@]}" -X DELETE \
              "${API}/repos/${OWNER}/${NAME}/releases/${rid}"
          done
          rm -f /tmp/all-releases.json
