name: Lint & Build

on:
  push:
    branches: [main]
    tags: ['v*']
  pull_request:
    branches: [main]
  workflow_dispatch:
    inputs:
      deploy:
        description: 'Deploy to ESP fleet after build'
        required: false
        default: 'false'
        type: choice
        options:
          - 'false'
          - 'true'

jobs:
  build:
    name: Build Firmware
    runs-on: anvil
    container:
      image: docker.io/espressif/idf:v5.3
    steps:
      - name: Checkout
        run: |
          git clone --depth=1 --branch=${{ github.ref_name }} \
            https://oauth2:${{ github.token }}@git.mymx.me/${{ github.repository }}.git .

      - name: Build firmware
        run: |
          . /opt/esp/idf/export.sh
          cd get-started/csi_recv_router
          idf.py build

      - name: Show binary size
        run: |
          ls -lh get-started/csi_recv_router/build/*.bin

      - name: Upload firmware artifact
        run: |
          mkdir -p /tmp/artifacts
          cp get-started/csi_recv_router/build/csi_recv_router.bin /tmp/artifacts/
          cp get-started/csi_recv_router/build/bootloader/bootloader.bin /tmp/artifacts/
          cp get-started/csi_recv_router/build/partition_table/partition-table.bin /tmp/artifacts/
          cp get-started/csi_recv_router/build/ota_data_initial.bin /tmp/artifacts/
          echo "Artifacts ready in /tmp/artifacts"
          ls -la /tmp/artifacts/

  deploy:
    name: Deploy to ESP Fleet
    runs-on: anvil
    needs: build
    if: github.event_name == 'workflow_dispatch' && github.event.inputs.deploy == 'true' || startsWith(github.ref, 'refs/tags/v')
    container:
      image: docker.io/espressif/idf:v5.3
    steps:
      - name: Install tools
        run: |
          apt-get update && apt-get install -y --no-install-recommends netcat-openbsd curl jq

      - name: Checkout
        run: |
          git clone --depth=1 --branch=${{ github.ref_name }} \
            https://oauth2:${{ github.token }}@git.mymx.me/${{ github.repository }}.git .

      - name: Build firmware
        run: |
          . /opt/esp/idf/export.sh
          cd get-started/csi_recv_router
          idf.py build

      - name: Create release and upload firmware
        env:
          GITEA_TOKEN: ${{ github.token }}
        run: |
          TAG="${{ github.ref_name }}"
          REPO="${{ github.repository }}"
          API_URL="https://git.mymx.me/api/v1"

          echo "Creating release for tag: $TAG"

          # Check if release exists
          RELEASE=$(curl -s -H "Authorization: token $GITEA_TOKEN" \
            "$API_URL/repos/$REPO/releases/tags/$TAG")

          RELEASE_ID=$(echo "$RELEASE" | jq -r '.id // empty')

          if [ -z "$RELEASE_ID" ]; then
            # Create new release
            RELEASE=$(curl -s -X POST -H "Authorization: token $GITEA_TOKEN" \
              -H "Content-Type: application/json" \
              -d "{\"tag_name\": \"$TAG\", \"name\": \"$TAG\", \"body\": \"Automated release from CI\"}" \
              "$API_URL/repos/$REPO/releases")
            RELEASE_ID=$(echo "$RELEASE" | jq -r '.id')
            echo "Created release ID: $RELEASE_ID"
          else
            echo "Release exists with ID: $RELEASE_ID"
          fi

          # Upload firmware binary
          echo "Uploading firmware..."
          curl -s -X POST -H "Authorization: token $GITEA_TOKEN" \
            -F "attachment=@get-started/csi_recv_router/build/csi_recv_router.bin" \
            "$API_URL/repos/$REPO/releases/$RELEASE_ID/assets?name=csi_recv_router.bin"

      - name: Deploy via OTA
        run: |
          SENSORS="muddy-storm:192.168.129.29 amber-maple:192.168.129.30 hollow-acorn:192.168.129.31"
          FIRMWARE_PATH="get-started/csi_recv_router/build/csi_recv_router.bin"
          OTA_PORT=8899

          # Get runner IP (first non-loopback interface)
          RUNNER_IP=$(hostname -I | awk '{print $1}')
          echo "Runner IP: $RUNNER_IP"

          # Start HTTP server to serve firmware
          cd get-started/csi_recv_router/build
          python3 -m http.server $OTA_PORT &
          HTTP_PID=$!
          sleep 2

          FIRMWARE_URL="http://${RUNNER_IP}:${OTA_PORT}/csi_recv_router.bin"
          echo "Firmware URL: $FIRMWARE_URL"

          # Verify server is running
          curl -sI "http://localhost:${OTA_PORT}/csi_recv_router.bin" | head -1

          # Deploy to each sensor
          for entry in $SENSORS; do
            NAME="${entry%%:*}"
            IP="${entry##*:}"
            echo "=== Deploying to $NAME ($IP) ==="
            echo "OTA $FIRMWARE_URL" | nc -u -w 2 "$IP" 5501 || true
            sleep 45
          done

          # Stop HTTP server
          kill $HTTP_PID 2>/dev/null || true

          echo "=== Deployment complete ==="

  cppcheck:
    name: C/C++ Static Analysis
    runs-on: anvil
    container:
      image: docker.io/library/debian:bookworm-slim
    steps:
      - name: Install tools
        run: |
          apt-get update && apt-get install -y --no-install-recommends git cppcheck ca-certificates

      - name: Checkout
        run: |
          git clone --depth=1 --branch=${{ github.ref_name }} \
            https://oauth2:${{ github.token }}@git.mymx.me/${{ github.repository }}.git .

      - name: Run cppcheck
        run: |
          cppcheck --enable=warning,style,performance,portability \
            --suppress=missingIncludeSystem \
            --error-exitcode=1 \
            --inline-suppr \
            -I get-started/csi_recv_router/main \
            get-started/csi_recv_router/main/*.c

  flawfinder:
    name: Security Flaw Analysis
    runs-on: anvil
    container:
      image: docker.io/library/python:3.12-slim
    steps:
      - name: Install tools
        run: |
          apt-get update && apt-get install -y --no-install-recommends git ca-certificates
          pip install --no-cache-dir flawfinder

      - name: Checkout
        run: |
          git clone --depth=1 --branch=${{ github.ref_name }} \
            https://oauth2:${{ github.token }}@git.mymx.me/${{ github.repository }}.git .

      - name: Run flawfinder
        run: |
          flawfinder --minlevel=2 --error-level=4 \
            get-started/csi_recv_router/main/

  gitleaks:
    name: Secret Scanning
    runs-on: anvil
    container:
      image: docker.io/zricethezav/gitleaks:latest
    steps:
      - name: Checkout
        run: |
          git clone --branch=${{ github.ref_name }} \
            https://oauth2:${{ github.token }}@git.mymx.me/${{ github.repository }}.git .

      - name: Run gitleaks
        run: gitleaks detect --source . --verbose --redact

  shellcheck:
    name: Shell Script Analysis
    runs-on: anvil
    container:
      image: docker.io/koalaman/shellcheck-alpine:stable
    steps:
      - name: Install git
        run: apk add --no-cache git

      - name: Checkout
        run: |
          git clone --depth=1 --branch=${{ github.ref_name }} \
            https://oauth2:${{ github.token }}@git.mymx.me/${{ github.repository }}.git .

      - name: Find and check shell scripts
        run: |
          SCRIPTS=$(find . -name "*.sh" -type f 2>/dev/null || true)
          if [ -n "$SCRIPTS" ]; then
            echo "Checking: $SCRIPTS"
            echo "$SCRIPTS" | xargs shellcheck --severity=warning
          else
            echo "No shell scripts found, skipping"
          fi
