name: Build and Deploy

on:
  push:
    branches: [ "*" ]
    tags:   [ "v*" ]
  pull_request:

jobs:
  # ──────────────────────────────────────────────────────────────
  #  LINUX BUILD
  # ──────────────────────────────────────────────────────────────
  build-linux:
    runs-on: ubuntu-latest
    container:
      image: gitea.pockle.world/john/prosperon/linux:latest

    steps:
      - name: Check Out Code
        uses: actions/checkout@v4
        with: { fetch-depth: 0 }

      - name: Build Prosperon (Linux)
        run: |
          meson setup build -Dbuildtype=release -Db_lto=true -Db_lto_mode=thin -Db_ndebug=true
          meson compile -C build

      - name: Test Prosperon (Linux)
        env: { TRACY_NO_INVARIANT_CHECK: 1 }
        run: |
          meson test --print-errorlogs -C build

      - name: Upload Test Log (Linux)
        if: ${{ always() }}
        uses: actions/upload-artifact@v3
        with:
          name: testlog-linux
          path: build/meson-logs/testlog.txt

      - name: Upload Artifact (Linux)
        if: startsWith(github.ref, 'refs/tags/v')
        uses: actions/upload-artifact@v3
        with:
          name: prosperon-artifacts-linux
          path: build/prosperon
          
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
          
      - name: Log in to Gitea Registry
        uses: docker/login-action@v3
        with:
          registry: gitea.pockle.world
          username: ${{ secrets.USER_GITEA }}
          password: ${{ secrets.TOKEN_GITEA }}
      
      - name: Determine Docker Tag
        id: docker_tag
        run: |
          if [[ "${{ github.ref }}" =~ ^refs/tags/v.* ]]; then
            TAG=$(echo "${{ github.ref }}" | sed 's#refs/tags/##')
            echo "tag=$TAG" >> $GITHUB_OUTPUT
          else
            echo "tag=latest" >> $GITHUB_OUTPUT
          fi
      
      - name: Build and Push Docker Image
        uses: docker/build-push-action@v6
        with:
          context: .
          file: ./Dockerfile
          push: true
          tags: gitea.pockle.world/john/prosperon:${{ steps.docker_tag.outputs.tag }}
          platforms: linux/amd64

  # ──────────────────────────────────────────────────────────────
  #  WINDOWS BUILD (MSYS2 / CLANG64)
  # ──────────────────────────────────────────────────────────────
  build-windows:
    runs-on: win-native
    strategy:
      matrix: { msystem: [ CLANG64 ] }

    steps:
      - name: Check Out Code
        uses: actions/checkout@v4

      - name: Setup MSYS2
        uses: msys2/setup-msys2@v2
        with:
          msystem: ${{ matrix.msystem }}
          update: true
          cache: true
          install: |
            git zip gzip tar base-devel
          pacboy: |
            meson
            cmake
            toolchain

      - name: Build Prosperon (Windows)
        shell: msys2 {0}
        run: |
          meson setup build -Dbuildtype=release -Db_lto=true -Db_lto_mode=thin -Db_ndebug=true -Dtracy:only_localhost=true -Dtracy:no_broadcast=true
          meson compile -C build

      - name: Test Prosperon (Windows)
        shell: msys2 {0}
        env:
          TRACY_NO_INVARIANT_CHECK: 1
        run: |
          meson test --print-errorlogs -C build

      - name: Upload Test Log (Windows)
        if: ${{ always() }}
        uses: actions/upload-artifact@v3
        with:
          name: testlog-windows
          path: build/meson-logs/testlog.txt

      - name: Upload Artifact (Windows)
        if: startsWith(github.ref, 'refs/tags/v')
        uses: actions/upload-artifact@v3
        with:
          name: prosperon-artifacts-windows
          path: build/prosperon.exe

  # ──────────────────────────────────────────────────────────────
  #  MACOS BUILD
  # ──────────────────────────────────────────────────────────────
  build-macos:
    runs-on: macos-latest

    steps:
      - name: Check Out Code
        uses: actions/checkout@v4
        with: { fetch-depth: 0 }
          
      - name: Build Prosperon (macOS)
        run: |
          meson setup build -Dbuildtype=release -Db_lto=true -Db_lto_mode=thin -Db_ndebug=true
          meson compile -C build
          
      - name: Test Prosperon (macOS)
        run: |
          meson test --print-errorlogs -C build

      - name: Upload Test Log (macOS)
        if: ${{ always() }}
        uses: actions/upload-artifact@v3
        with:
          name: testlog-macos
          path: build/meson-logs/testlog.txt

      - name: Upload Artifact (macOS)
        if: startsWith(github.ref, 'refs/tags/v')
        uses: actions/upload-artifact@v3
        with:
          name: prosperon-artifacts-macos
          path: build/prosperon

  # ──────────────────────────────────────────────────────────────
  #  PACKAGE CROSS-PLATFORM DIST
  # ──────────────────────────────────────────────────────────────
  package-dist:
    needs: [ build-linux, build-windows, build-macos ]
    if: startsWith(github.ref, 'refs/tags/v')
    runs-on: ubuntu-latest

    steps:
      - name: Check Out Code
        uses: actions/checkout@v3
        with: { fetch-depth: 0 }

      - name: Get Latest Tag
        id: get_tag
        run: |
          TAG=$(git describe --tags --abbrev=0)
          echo "tag=$TAG" >> $GITHUB_OUTPUT

      - name: Download Linux Artifacts
        uses: actions/download-artifact@v3
        with:
          name: prosperon-artifacts-linux
          path: linux_artifacts

      - name: Download Windows Artifacts
        uses: actions/download-artifact@v3
        with:
          name: prosperon-artifacts-windows
          path: windows_artifacts

      - name: Download macOS Artifacts
        uses: actions/download-artifact@v3
        with:
          name: prosperon-artifacts-macos
          path: mac_artifacts

      - name: Create Dist Folder
        run: |
          mkdir -p dist/linux dist/win dist/mac
          cp README.md        dist/
          cp license.txt      dist/
          cp -r examples      dist/
          cp linux_artifacts/*   dist/linux/
          cp windows_artifacts/* dist/win/
          cp mac_artifacts/*     dist/mac/

      - name: Package Final Dist
        run: |
          TAG=${{ steps.get_tag.outputs.tag }}
          zip -r "prosperon-${TAG}.zip" dist
          echo "Created prosperon-${TAG}.zip"

      - name: Upload Final Dist
        uses: actions/upload-artifact@v3
        with:
          name: "prosperon-${{ steps.get_tag.outputs.tag }}"
          path: "prosperon-${{ steps.get_tag.outputs.tag }}.zip"

  # ──────────────────────────────────────────────────────────────
  #  DEPLOY TO ITCH.IO   (single ZIP containing all OSes)
  # ──────────────────────────────────────────────────────────────
  deploy-itch:
    needs: [ package-dist ]
    runs-on: ubuntu-latest

    steps:
      - name: Check Out Code
        uses: actions/checkout@v3
        with: { fetch-depth: 0 }

      - name: Get Latest Tag
        id: get_tag
        run: |
          TAG=$(git describe --tags --abbrev=0)
          echo "tag=$TAG" >> $GITHUB_OUTPUT

      - name: Download Final Distribution
        uses: actions/download-artifact@v3
        with:
          name: "prosperon-${{ steps.get_tag.outputs.tag }}"
          path: dist

      - name: Set up Butler
        uses: jdno/setup-butler@v1

      - name: Push to itch.io
        run: |
          butler push "dist/prosperon-${{ steps.get_tag.outputs.tag }}.zip" \
            ${{ secrets.ITCHIO_USERNAME }}/prosperon:universal \
            --userversion ${{ steps.get_tag.outputs.tag }}
        env:
          BUTLER_API_KEY: ${{ secrets.ITCHIO_API_KEY }}

  # ──────────────────────────────────────────────────────────────
  #  DEPLOY TO SELF-HOSTED GITEA
  # ──────────────────────────────────────────────────────────────
  deploy-gitea:
    needs: [ package-dist ]
    runs-on: ubuntu-latest

    steps:
      - name: Check Out Code
        uses: actions/checkout@v3
        with: { fetch-depth: 0 }

      - name: Get Latest Tag & Commit Message
        id: get_tag
        run: |
          TAG=$(git describe --tags --abbrev=0)
          COMMIT_MSG=$(git log -1 --pretty=%B "$TAG")
          echo "tag=$TAG"        >> $GITHUB_OUTPUT
          echo "commit_msg=$COMMIT_MSG" >> $GITHUB_OUTPUT

      - name: Download Final Distribution
        uses: actions/download-artifact@v3
        with:
          name: "prosperon-${{ steps.get_tag.outputs.tag }}"
          path: dist

      - name: Create / Update Gitea Release
        run: |
          TAG=${{ steps.get_tag.outputs.tag }}
          ZIP=dist/prosperon-${TAG}.zip
          BODY=$(echo "${{ steps.get_tag.outputs.commit_msg }}" | jq -R -s '.')
          RELEASE=$(curl -s -H "Authorization: token ${{ secrets.TOKEN_GITEA }}" \
            "https://gitea.pockle.world/api/v1/repos/john/prosperon/releases/tags/$TAG" | jq -r '.id')

          if [ "$RELEASE" = "null" ] || [ -z "$RELEASE" ]; then
            RELEASE=$(curl -X POST \
              -H "Authorization: token ${{ secrets.TOKEN_GITEA }}" \
              -H "Content-Type: application/json" \
              -d "{\"tag_name\":\"$TAG\",\"target_commitish\":\"${{ github.sha }}\",\"name\":\"$TAG\",\"body\":$BODY,\"draft\":false,\"prerelease\":false}" \
              "https://gitea.pockle.world/api/v1/repos/john/prosperon/releases" | jq -r '.id')
          fi

          curl -X POST \
            -H "Authorization: token ${{ secrets.TOKEN_GITEA }}" \
            -H "Content-Type: application/octet-stream" \
            --data-binary @"$ZIP" \
            "https://gitea.pockle.world/api/v1/repos/john/prosperon/releases/$RELEASE/assets?name=prosperon-${TAG}.zip"
        env:
          TOKEN_GITEA: ${{ secrets.TOKEN_GITEA }}
