name: Build

on:
  workflow_call:
    inputs:
      version:
        required: true
        type: string
      platform:
        required: true
        type: string
      pio_env:
        required: true
        type: string

permissions: read-all

jobs:
  pio-build:
    name: build-${{ inputs.platform }}
    # Use 'arctastic' self-hosted runner pool when building in the main repo
    runs-on: ${{ github.repository_owner == 'meshtastic' && 'arctastic' || 'ubuntu-latest' }}
    outputs:
      artifact-id: ${{ steps.upload-firmware.outputs.artifact-id }}
    steps:
      - uses: actions/checkout@v6
        with:
          submodules: recursive

      - name: Build ${{ inputs.platform }}
        id: build
        uses: meshtastic/gh-action-firmware@main
        with:
          pio_platform: ${{ inputs.platform }}
          pio_env: ${{ inputs.pio_env }}
          pio_target: build

      - name: ESP32 - Download Unified OTA firmware
        # Currently only esp32 and esp32s3 use the unified ota
        if: inputs.platform == 'esp32' || inputs.platform == 'esp32s3'
        id: dl-ota-unified
        env:
          PIO_PLATFORM: ${{ inputs.platform }}
          PIO_ENV: ${{ inputs.pio_env }}
          OTA_URL: https://github.com/meshtastic/esp32-unified-ota/releases/latest/download/mt-${{ inputs.platform }}-ota.bin
        working-directory: release
        run: |
          curl -L -o "mt-$PIO_PLATFORM-ota.bin" $OTA_URL

      - name: ESP32-C* - Download BLE-Only OTA firmware
        if: inputs.platform == 'esp32c3' || inputs.platform == 'esp32c6'
        id: dl-ota-ble
        env:
          PIO_ENV: ${{ inputs.pio_env }}
          OTA_URL: https://github.com/meshtastic/firmware-ota/releases/latest/download/firmware-c3.bin
        working-directory: release
        run: |
          curl -L -o bleota-c3.bin $OTA_URL

      - name: Update manifest with OTA file
        if: inputs.platform == 'esp32' || inputs.platform == 'esp32s3' || inputs.platform == 'esp32c3' || inputs.platform == 'esp32c6'
        working-directory: release
        env:
          PIO_PLATFORM: ${{ inputs.platform }}
        run: |
          # Determine OTA filename based on platform
          if [[ "$PIO_PLATFORM" == "esp32" || "$PIO_PLATFORM" == "esp32s3" ]]; then
            OTA_FILE="mt-${PIO_PLATFORM}-ota.bin"
          else
            OTA_FILE="bleota-c3.bin"
          fi

          # Check if OTA file exists
          if [[ ! -f "$OTA_FILE" ]]; then
            echo "OTA file $OTA_FILE not found, skipping manifest update"
            exit 0
          fi

          # Calculate MD5 and size
          if command -v md5sum &> /dev/null; then
            OTA_MD5=$(md5sum "$OTA_FILE" | cut -d' ' -f1)
          else
            OTA_MD5=$(md5 -q "$OTA_FILE")
          fi
          OTA_SIZE=$(stat -f%z "$OTA_FILE" 2>/dev/null || stat -c%s "$OTA_FILE")

          # Find and update manifest file
          for manifest in firmware-*.mt.json; do
            if [[ -f "$manifest" ]]; then
              echo "Updating $manifest with $OTA_FILE (md5: $OTA_MD5, size: $OTA_SIZE)"
              # Add OTA entry to files array if not already present
              jq --arg name "$OTA_FILE" --arg md5 "$OTA_MD5" --argjson bytes "$OTA_SIZE" --arg part "app1" \
                'if .files | map(select(.name == $name)) | length == 0 then .files += [{"name": $name, "md5": $md5, "bytes": $bytes, "part_name": $part}] else . end' \
                "$manifest" > "${manifest}.tmp" && mv "${manifest}.tmp" "$manifest"
            fi
          done

      - name: Job summary
        env:
          PIO_ENV: ${{ inputs.pio_env }}
        run: |
          echo "## $PIO_ENV" >> $GITHUB_STEP_SUMMARY
          echo "<details><summary><strong>Manifest</strong></summary>" >> $GITHUB_STEP_SUMMARY
          echo '' >> $GITHUB_STEP_SUMMARY
          echo '```json' >> $GITHUB_STEP_SUMMARY
          cat release/firmware-*.mt.json >> $GITHUB_STEP_SUMMARY
          echo '' >> $GITHUB_STEP_SUMMARY
          echo '```' >> $GITHUB_STEP_SUMMARY
          echo "</details>" >> $GITHUB_STEP_SUMMARY

      - name: Store binaries as an artifact
        uses: actions/upload-artifact@v7
        id: upload-firmware
        with:
          name: firmware-${{ inputs.platform }}-${{ inputs.pio_env }}-${{ inputs.version }}
          overwrite: true
          path: |
            release/*.mt.json
            release/*.bin
            release/*.elf
            release/*.uf2
            release/*.hex
            release/*.zip
            release/device-*.sh
            release/device-*.bat

      - name: Store manifests as an artifact
        uses: actions/upload-artifact@v7
        id: upload-manifest
        with:
          name: manifest-${{ inputs.platform }}-${{ inputs.pio_env }}-${{ inputs.version }}
          overwrite: true
          path: |
            release/*.mt.json
