name: Validate Balatro Mods

on:
  pull_request:
    paths:
      - "mods/**"

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - name: Check out repository
        uses: actions/checkout@v3
        with:
          fetch-depth: 0  # Get full history for comparing changes

      - name: Use ImageMagick from cache
        uses: awalsh128/cache-apt-pkgs-action@v1
        with:
          packages: imagemagick
          version: 8:6.9.12.98+dfsg1-5.2build2

      - name: Identify Changed Mods
        id: find-changed-mods
        run: |
          # Get the list of files changed in the PR using GitHub API
          API_RESPONSE=$(curl -s -X GET \
            -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
            -H "Accept: application/vnd.github.v3+json" \
            "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files")

          # Use fallback method if API fails
          if echo "$API_RESPONSE" | jq -e 'if type=="array" then true else false end' > /dev/null; then
            echo "Using GitHub API method to find changed files"
            echo "$API_RESPONSE" | jq -r '.[] | .filename' | grep -E '^mods/[^/]+/' | cut -d'/' -f1-2 | sort | uniq > changed_mods.txt
          else
            echo "Using git diff method as fallback"
            # Fetch the base branch of the PR
            git fetch origin ${{ github.event.pull_request.base.ref }}
            
            # Find all added or modified files in mods directory using git diff
            git diff --name-only --diff-filter=AM origin/${{ github.event.pull_request.base.ref }}..HEAD | grep -E '^mods/[^/]+/' | cut -d'/' -f1-2 | sort | uniq > changed_mods.txt
          fi
          
          # Check if any mods were found
          if [ ! -s changed_mods.txt ]; then
            echo "No mods were added or modified in this PR."
            echo "changed_mods_found=false" >> $GITHUB_OUTPUT
            exit 0
          fi
          
          echo "Changed mods found:"
          cat changed_mods.txt
          echo "changed_mods_found=true" >> $GITHUB_OUTPUT
          
          # Create a newline-separated list for JSON schema validation
          META_JSON_FILES=$(while read -r mod_path; do
            [ -f "$mod_path/meta.json" ] && echo "$mod_path/meta.json"
          done < changed_mods.txt)
                  
          echo "meta_json_files<<EOF" >> $GITHUB_OUTPUT
          echo "$META_JSON_FILES" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      - name: Check Required Files
        if: steps.find-changed-mods.outputs.changed_mods_found == 'true'
        run: |
          while read -r mod_path; do
            if [ -d "$mod_path" ]; then
              MOD_DIR="$(basename "$mod_path")"
              
              # Ensure description.md and meta.json exist
              if [ ! -f "$mod_path/description.md" ]; then
                echo "Error: Missing description.md in $MOD_DIR"
                exit 1
              fi
              
              if [ ! -f "$mod_path/meta.json" ]; then
                echo "Error: Missing meta.json in $MOD_DIR"
                exit 1
              fi
            fi
          done < changed_mods.txt

      - name: Check Thumbnail Dimensions
        if: always() && steps.find-changed-mods.outputs.changed_mods_found == 'true'
        run: |
          while read -r mod_path; do
            if [ -d "$mod_path" ]; then
              MOD_DIR="$(basename "$mod_path")"
              THUMBNAIL="$mod_path/thumbnail.jpg"
              
              if [ -f "$THUMBNAIL" ]; then
                # Extract width and height using ImageMagick identify
                # Using identify-im6.q16 directly as identify is a symlink that is not created by the cache restoration
                DIMENSIONS=$(/usr/bin/identify-im6.q16 -format "%wx%h" "$THUMBNAIL")
                WIDTH=$(echo "$DIMENSIONS" | cut -dx -f1)
                HEIGHT=$(echo "$DIMENSIONS" | cut -dx -f2)
                
                # Check if dimensions exceed 1920x1080
                if [ "$WIDTH" -gt 1920 ] || [ "$HEIGHT" -gt 1080 ]; then
                  echo "Error: Thumbnail in $MOD_DIR exceeds the recommended size of 1920×1080."
                  exit 1
                fi
              fi
            fi
          done < changed_mods.txt

      - name: Validate JSON Format
        if: always() && steps.find-changed-mods.outputs.changed_mods_found == 'true'
        run: |
          # Use jq to validate each JSON file
          while read -r mod_path; do
            if [ -f "$mod_path/meta.json" ]; then
              if ! jq empty "$mod_path/meta.json" 2>/dev/null; then
                echo "Error: Invalid JSON format in $mod_path/meta.json"
                exit 1
              fi
            fi
          done < changed_mods.txt

      - name: Validate meta.json Against Schema
        if: always() && steps.find-changed-mods.outputs.changed_mods_found == 'true'
        uses: dsanders11/json-schema-validate-action@v1.4.0
        with:
          schema: "./schema/meta.schema.json"
          files: ${{ steps.find-changed-mods.outputs.meta_json_files }}
          custom-errors: true

      - name: Validate Download URLs
        if: always() && steps.find-changed-mods.outputs.changed_mods_found == 'true'
        run: |
          while read -r mod_path; do
            if [ -d "$mod_path" ]; then
              MOD_DIR="$(basename "$mod_path")"
              META_JSON="$mod_path/meta.json"
              
              # Check if downloadURL exists and is not empty
              DOWNLOAD_URL=$(jq -r '.downloadURL // empty' "$META_JSON")
              if [ -z "$DOWNLOAD_URL" ]; then
                echo "Error: Missing or empty downloadURL in $MOD_DIR/meta.json"
                exit 1
              fi
              
              # Optional: Check if URL is accessible
              if ! curl --output /dev/null --silent --head --fail "$DOWNLOAD_URL"; then
                echo "Error: downloadURL in $MOD_DIR/meta.json is not accessible"
                exit 1
              fi
            fi
          done < changed_mods.txt
