name: Publish MultiLoader mod

on:
  push:
    tags:
      - 'v*'

permissions:
  contents: write

# For Jaredlll08's MultiLoader-Template with fabric/ and neoforge/ subprojects.
# Change these four values. The mod version comes from the tag.
env:
  MOD_NAME: example-mod
  MINECRAFT_VERSION: 1.21.1
  JAVA_VERSION: '21'
  MOD_SIDE: both # both, client, server or either

jobs:
  release:
    runs-on: ubuntu-latest

    steps:
      - name: Check out the tagged source
        uses: actions/checkout@v6

      - name: Set up Java
        uses: actions/setup-java@v5
        with:
          distribution: temurin
          java-version: ${{ env.JAVA_VERSION }}

      - name: Set up Gradle
        uses: gradle/actions/setup-gradle@v6

      - name: Build the Fabric and NeoForge subprojects
        run: |
          chmod +x ./gradlew
          ./gradlew :fabric:build :neoforge:build --no-daemon

      - name: Prepare both playable JARs and Modpacks.ch metadata
        shell: bash
        run: |
          set -euo pipefail

          MOD_VERSION="${GITHUB_REF_NAME#v}"
          FABRIC_OUTPUT="${MOD_NAME}-${MINECRAFT_VERSION}-${MOD_VERSION}-fabric.jar"
          NEOFORGE_OUTPUT="${MOD_NAME}-${MINECRAFT_VERSION}-${MOD_VERSION}-neoforge.jar"

          if [[ ! "${MOD_NAME}" =~ ^[A-Za-z0-9][A-Za-z0-9._-]*$ ]] ||
             [[ ! "${MINECRAFT_VERSION}" =~ ^[A-Za-z0-9][A-Za-z0-9._+-]*$ ]] ||
             [[ ! "${MOD_VERSION}" =~ ^[A-Za-z0-9][A-Za-z0-9._+-]*$ ]]; then
            echo 'MOD_NAME, MINECRAFT_VERSION and the tag must be safe filename values'
            exit 1
          fi

          find_playable_jar() {
            local directory="$1"
            mapfile -t FOUND < <(
              find "${directory}" -maxdepth 1 -type f -name '*.jar' \
                ! -name '*-sources.jar' \
                ! -name '*-dev.jar' \
                ! -name '*-dev-shadow.jar' \
                ! -name '*-javadoc.jar'
            )

            if [[ "${#FOUND[@]}" -ne 1 ]]; then
              printf 'Expected one playable JAR in %s, found %s:\n' "${directory}" "${#FOUND[@]}" >&2
              printf '  %s\n' "${FOUND[@]}" >&2
              return 1
            fi

            printf '%s' "${FOUND[0]}"
          }

          FABRIC_JAR="$(find_playable_jar fabric/build/libs)"
          NEOFORGE_JAR="$(find_playable_jar neoforge/build/libs)"

          case "${MOD_SIDE}" in
            both) CLIENT=required; SERVER=required ;;
            client) CLIENT=required; SERVER=unsupported ;;
            server) CLIENT=unsupported; SERVER=required ;;
            either) CLIENT=optional; SERVER=optional ;;
            *) echo 'MOD_SIDE must be both, client, server or either'; exit 1 ;;
          esac

          mkdir -p release
          cp "${FABRIC_JAR}" "release/${FABRIC_OUTPUT}"
          cp "${NEOFORGE_JAR}" "release/${NEOFORGE_OUTPUT}"

          jq -n \
            --arg fabricAsset "${FABRIC_OUTPUT}" \
            --arg neoforgeAsset "${NEOFORGE_OUTPUT}" \
            --arg mc "${MINECRAFT_VERSION}" \
            --arg client "${CLIENT}" \
            --arg server "${SERVER}" \
            '{
              "$schema": "https://modpacks.ch/schemas/github-release-v1.json",
              "version": 1,
              "files": [
                {
                  "name": ($fabricAsset | sub("\\.jar$"; "")),
                  "asset": $fabricAsset,
                  "targets": {
                    "gameVersions": [$mc],
                    "loaders": ["fabric"]
                  },
                  "environment": {
                    "client": $client,
                    "server": $server
                  },
                  "dependencies": []
                },
                {
                  "name": ($neoforgeAsset | sub("\\.jar$"; "")),
                  "asset": $neoforgeAsset,
                  "targets": {
                    "gameVersions": [$mc],
                    "loaders": ["neoforge"]
                  },
                  "environment": {
                    "client": $client,
                    "server": $server
                  },
                  "dependencies": []
                }
              ]
            }' > release/modpacksch-release.json

      - name: Publish the GitHub Release
        env:
          GH_TOKEN: ${{ github.token }}
        shell: bash
        run: |
          set -euo pipefail

          if gh release view "${GITHUB_REF_NAME}" >/dev/null 2>&1; then
            gh release upload "${GITHUB_REF_NAME}" \
              release/*.jar \
              release/modpacksch-release.json \
              --clobber
          else
            gh release create "${GITHUB_REF_NAME}" \
              release/*.jar \
              release/modpacksch-release.json \
              --verify-tag \
              --generate-notes \
              --title "${MOD_NAME} ${GITHUB_REF_NAME#v}"
          fi
