name: Deploy DEV Workshop

on:
  push:
    branches:
      - main

env:
  STEAM_APP_ID: "107410"
  HOST_REPO: /data/valmo/braf
  HOST_CACHE: /data/valmo/braf-ci-cache/dev-workshop
  BRAF_CI_STAGE_DIR: dist/dev/@braf_dev

jobs:
  deploy-dev-workshop:
    runs-on: ubuntu-latest

    steps:
      - name: Build changed addons and upload DEV Workshop item
        shell: bash
        env:
          GIT_SHA: ${{ github.sha }}
          GIT_BEFORE: ${{ github.event.before }}
          GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
          GITHUB_TOKEN: ${{ github.token }}
          STEAM_USERNAME: ${{ secrets.STEAM_USERNAME }}
          STEAM_PASSWORD: ${{ secrets.STEAM_PASSWORD }}
          STEAM_DEV_ITEM_ID: ${{ secrets.STEAM_DEV_ITEM_ID }}
        run: |
          set -euo pipefail


          docker run --rm -i \
            --user root \
            -e BRAF_CI_STAGE_DIR \
            -e GIT_BEFORE \
            -e GIT_SHA \
            -e GITEA_TOKEN \
            -e GITHUB_TOKEN \
            -e HOST_CACHE \
            -e HOST_REPO \
            -e STEAM_APP_ID \
            -e STEAM_DEV_ITEM_ID \
            -e STEAM_PASSWORD \
            -e STEAM_USERNAME \
            -v "$HOST_REPO:/repo" \
            -v "$HOST_CACHE:/cache" \
            -v /var/run/docker.sock:/var/run/docker.sock \
            valmo/braf-mikero:3.23.8.60 \
            bash -s <<'BRAF_CI'
          set -euo pipefail

          install_runtime() {
            export DEBIAN_FRONTEND=noninteractive
            apt-get update
            apt-get install -y \
              ca-certificates \
              curl \
              git-lfs \
              libogg0 \
              libuchardet0 \
              libvorbis0a \
              libvorbisenc2 \
              libvorbisfile3
          }

          install_mikero() {
            export WINEPREFIX=/cache/mikero-wine
            export WINEARCH=win64
            export WINEDEBUG=-all

            if ! command -v pboProject >/dev/null; then
              echo "pboProject is missing from valmo/braf-mikero image." >&2
              return 1
            fi

            if ! command -v winetricks >/dev/null; then
              apt-get install -y winetricks
            fi

            if [[ ! -f "$WINEPREFIX/drive_c/windows/system32/mfc140u.dll" ]]; then
              echo "Initializing the persistent Mikero Wine runtime."
              xvfb-run -a winetricks -q vcrun2015
            fi

            sed -i "s#exec /usr/lib/wine/wine64#exec xvfb-run -a /usr/bin/wine#" /usr/local/bin/pboProject
          }

          is_zero_sha() {
            [[ -z "${1:-}" || "$1" == "0000000000000000000000000000000000000000" ]]
          }

          addon_csv() {
            local IFS=,
            echo "$*"
          }

          configure_git_auth() {
            git_auth_args=()
            local token="${GITEA_TOKEN:-${GITHUB_TOKEN:-}}"
            if [[ -n "$token" ]]; then
              local basic_auth
              basic_auth="$(printf 'x-access-token:%s' "$token" | base64 | tr -d '\n')"
              git_auth_args=(
                -c "http.https://git.valmo.dev/.extraheader=AUTHORIZATION: Basic ${basic_auth}"
              )
            fi
          }

          git_auth() {
            git "${git_auth_args[@]}" "$@"
          }

          install_runtime
          install_mikero

          cd /repo
          git config --global --add safe.directory /repo
          configure_git_auth
          git lfs install --local
          git_auth fetch --no-tags origin "$GIT_SHA" || git_auth fetch --no-tags origin main

          if is_zero_sha "$GIT_BEFORE" || ! git cat-file -e "$GIT_BEFORE^{commit}" 2>/dev/null; then
            mapfile -t changed_addons < <(
              git ls-tree -d --name-only "$GIT_SHA" |
                awk '/^braf_/ {print}' |
                while read -r addon; do
                  if git cat-file -e "$GIT_SHA:$addon/config.cpp" 2>/dev/null; then
                    printf '%s\n' "$addon"
                  fi
                done
            )
            metadata_changed=true
          else
            mapfile -t changed_files < <(git diff --name-only "$GIT_BEFORE" "$GIT_SHA")
            mapfile -t changed_addons < <(
              printf '%s\n' "${changed_files[@]}" |
                awk -F/ '$1 ~ /^braf_/ {print $1}' |
                sort -u |
                while read -r addon; do
                  if git cat-file -e "$GIT_SHA:$addon/config.cpp" 2>/dev/null; then
                    printf '%s\n' "$addon"
                  fi
                done
            )

            metadata_changed=false
            if printf '%s\n' "${changed_files[@]}" | grep -Eq '^(mod\.cpp|meta\.cpp|make/ci_dev_workshop\.py|\.gitea/workflows/dev-workshop\.yml)$'; then
              metadata_changed=true
            fi
          fi

          if ! find /cache/pbo/addons -maxdepth 1 -name '*.pbo' -print -quit 2>/dev/null | grep -q .; then
            echo "PBO cache is empty; bootstrapping all buildable addons."
            mapfile -t changed_addons < <(
              git ls-tree -d --name-only "$GIT_SHA" |
                awk '/^braf_/ {print}' |
                while read -r addon; do
                  if git cat-file -e "$GIT_SHA:$addon/config.cpp" 2>/dev/null; then
                    printf '%s\n' "$addon"
                  fi
                done
            )
            metadata_changed=true
          fi

          if [[ "${#changed_addons[@]}" -eq 0 && "$metadata_changed" != "true" ]]; then
            echo "No addon or workshop metadata changes detected; skipping DEV Workshop deploy."
            exit 0
          fi

          GIT_LFS_SKIP_SMUDGE=1 git reset --hard "$GIT_SHA"

          if [[ "${#changed_addons[@]}" -gt 0 ]]; then
            include=""
            for addon in "${changed_addons[@]}"; do
              include+="${include:+,}${addon}/**"
            done

            echo "Changed addons: $(addon_csv "${changed_addons[@]}")"
            echo "Fetching LFS only for: $include"
            git_auth lfs fetch origin "$GIT_SHA" --include="$include" --exclude="*"
            git lfs checkout "${changed_addons[@]}"
          else
            echo "Only workshop metadata changed; seeding any missing PBO cache entries."
            mapfile -t changed_addons < <(
              git ls-tree -d --name-only "$GIT_SHA" |
                awk "/^braf_/ {print}" |
                while read -r addon; do
                  if git cat-file -e "$GIT_SHA:$addon/config.cpp" 2>/dev/null; then
                    printf "%s\n" "$addon"
                  fi
                done
            )
            include=""
            for addon in "${changed_addons[@]}"; do
              include+="${include:+,}${addon}/**"
            done
            echo "Fetching LFS for cache seed: $include"
            git_auth lfs fetch origin "$GIT_SHA" --include="$include" --exclude="*"
            git lfs checkout "${changed_addons[@]}"
          fi

          build_args=(
            --cache-dir /cache/pbo
            --stage-dir "$BRAF_CI_STAGE_DIR"
            --addons "$(addon_csv "${changed_addons[@]}")"
          )

          python3 -m make.ci_dev_workshop "${build_args[@]}"

          short_sha="$(git rev-parse --short "$GIT_SHA")"
          subject="$(git log -1 --pretty=%s)"
          changelog="DEV ${short_sha}: ${subject}"

          cat > /cache/braf-dev-workshop.vdf <<EOF
          "workshopitem"
          {
            "appid" "$STEAM_APP_ID"
            "publishedfileid" "$STEAM_DEV_ITEM_ID"
            "contentfolder" "/content"
            "changenote" "$changelog"
          }
          EOF

          docker run --rm \
            -e STEAM_PASSWORD \
            -e STEAM_USERNAME \
            -v "${HOST_REPO}/${BRAF_CI_STAGE_DIR}:/content:ro" \
            -v "${HOST_CACHE}/braf-dev-workshop.vdf:/tmp/braf-dev-workshop.vdf:ro" \
            cm2network/steamcmd:root \
            bash -lc '/home/steam/steamcmd/steamcmd.sh +login "$STEAM_USERNAME" "$STEAM_PASSWORD" +workshop_build_item /tmp/braf-dev-workshop.vdf +quit'
          BRAF_CI
