name: GDScript Auto-Formatting

on:
  # Trigger on pull requests to main branch
  pull_request:
    branches: ['main']
    paths:
      - '**/*.gd'
      - '.gdformatrc'
      - '.gitea/workflows/gdformat.yml'

  # Allow manual triggering
  workflow_dispatch:
    inputs:
      target_branch:
        description: 'Target branch to format (leave empty for current branch)'
        required: false
        default: ''

jobs:
  gdformat:
    name: Auto-Format GDScript Code
    runs-on: ubuntu-latest

    # Grant write permissions for pushing changes
    permissions:
      contents: write
      pull-requests: write

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          # Use the PR head ref for pull requests, or current branch for manual runs
          ref: ${{ github.event.pull_request.head.ref || github.ref }}
          # Need token with write permissions to push back
          token: ${{ secrets.GITHUB_TOKEN }}
          fetch-depth: 0

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.11'
          cache: 'pip'

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install --upgrade "setuptools<81"
          pip install gdtoolkit==4

      - name: Verify gdformat installation
        run: |
          gdformat --version
          echo "✅ gdformat installed successfully"

      - name: Get target branch info
        id: branch-info
        run: |
          if [[ "${{ github.event_name }}" == "pull_request" ]]; then
            target_branch="${{ github.event.pull_request.head.ref }}"
            echo "🔄 Processing PR branch: $target_branch"
          elif [[ -n "${{ github.event.inputs.target_branch }}" ]]; then
            target_branch="${{ github.event.inputs.target_branch }}"
            echo "🎯 Manual target branch: $target_branch"
            git checkout "$target_branch" || (echo "❌ Branch not found: $target_branch" && exit 1)
          else
            target_branch="${{ github.ref_name }}"
            echo "📍 Current branch: $target_branch"
          fi
          echo "target_branch=$target_branch" >> $GITHUB_OUTPUT

      - name: Count GDScript files
        id: count-files
        run: |
          file_count=$(find . -name "*.gd" -not -path "./.git/*" | wc -l)
          echo "file_count=$file_count" >> $GITHUB_OUTPUT
          echo "📊 Found $file_count GDScript files to format"

      - name: Run GDScript formatting
        id: format-files
        run: |
          echo "🎨 Starting GDScript formatting..."
          echo "================================"

          # Initialize counters
          total_files=0
          formatted_files=0
          skipped_files=0
          failed_files=0

          # Track if any files were actually changed
          files_changed=false

          # Find all .gd files except TestHelper.gd (static var syntax incompatibility)
          while IFS= read -r -d '' file; do
            filename=$(basename "$file")

            # Skip TestHelper.gd due to static var syntax incompatibility with gdformat
            if [[ "$filename" == "TestHelper.gd" ]]; then
              echo "⚠️  Skipping $file (static var syntax not supported by gdformat)"
              ((total_files++))
              ((skipped_files++))
              continue
            fi

            echo "🎨 Formatting: $file"
            ((total_files++))

            # Get file hash before formatting
            before_hash=$(sha256sum "$file" | cut -d' ' -f1)

            # Run gdformat
            if gdformat "$file" 2>/dev/null; then
              # Get file hash after formatting
              after_hash=$(sha256sum "$file" | cut -d' ' -f1)

              if [[ "$before_hash" != "$after_hash" ]]; then
                echo "✅ Formatted (changes applied)"
                files_changed=true
              else
                echo "✅ Already formatted"
              fi
              ((formatted_files++))
            else
              echo "❌ Failed to format"
              ((failed_files++))
            fi

          done < <(find . -name "*.gd" -not -path "./.git/*" -print0)

          # Print summary
          echo ""
          echo "================================"
          echo "📋 Formatting Summary"
          echo "================================"
          echo "📊 Total files: $total_files"
          echo "✅ Successfully formatted: $formatted_files"
          echo "⚠️  Skipped files: $skipped_files"
          echo "❌ Failed files: $failed_files"
          echo ""

          # Export results for next step
          echo "files_changed=$files_changed" >> $GITHUB_OUTPUT
          echo "total_files=$total_files" >> $GITHUB_OUTPUT
          echo "formatted_files=$formatted_files" >> $GITHUB_OUTPUT
          echo "failed_files=$failed_files" >> $GITHUB_OUTPUT

          # Exit with error if any files failed
          if [[ $failed_files -gt 0 ]]; then
            echo "❌ Formatting FAILED - $failed_files file(s) could not be formatted"
            exit 1
          else
            echo "✅ All files processed successfully!"
          fi

      - name: Check for changes
        id: check-changes
        run: |
          if git diff --quiet; then
            echo "📝 No formatting changes detected"
            echo "has_changes=false" >> $GITHUB_OUTPUT
          else
            echo "📝 Formatting changes detected"
            echo "has_changes=true" >> $GITHUB_OUTPUT

            # Show what changed
            echo "🔍 Changed files:"
            git diff --name-only
            echo ""
            echo "📊 Diff summary:"
            git diff --stat
          fi

      - name: Commit and push changes
        if: steps.check-changes.outputs.has_changes == 'true'
        run: |
          echo "💾 Committing formatting changes..."

          # Configure git
          git config user.name "Gitea Actions"
          git config user.email "actions@gitea.local"

          # Add all changed files
          git add -A

          # Create commit with detailed message
          commit_message="🎨 Auto-format GDScript code

          Automated formatting applied by gdformat workflow

          📊 Summary:
          - Total files processed: ${{ steps.format-files.outputs.total_files }}
          - Successfully formatted: ${{ steps.format-files.outputs.formatted_files }}
          - Files with changes: $(git diff --cached --name-only | wc -l)

          🤖 Generated by Gitea Actions
          Workflow: ${{ github.workflow }}
          Run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"

          git commit -m "$commit_message"

          # Push changes back to the branch
          target_branch="${{ steps.branch-info.outputs.target_branch }}"
          echo "📤 Pushing changes to branch: $target_branch"

          git push origin HEAD:"$target_branch"

          echo "✅ Changes pushed successfully!"

      - name: Summary comment (PR only)
        if: github.event_name == 'pull_request'
        uses: actions/github-script@v6
        with:
          script: |
            const hasChanges = '${{ steps.check-changes.outputs.has_changes }}' === 'true';
            const totalFiles = '${{ steps.format-files.outputs.total_files }}';
            const formattedFiles = '${{ steps.format-files.outputs.formatted_files }}';
            const failedFiles = '${{ steps.format-files.outputs.failed_files }}';

            let message;
            if (hasChanges) {
              message = `🎨 **GDScript Auto-Formatting Complete**

              ✅ Code has been automatically formatted and pushed to this branch.

              📊 **Summary:**
              - Total files processed: ${totalFiles}
              - Successfully formatted: ${formattedFiles}
              - Files with changes applied: ${hasChanges ? 'Yes' : 'No'}

              🔄 **Next Steps:**
              The latest commit contains the formatted code. You may need to pull the changes locally.

              [View workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})`;
            } else {
              message = `🎨 **GDScript Formatting Check**

              ✅ All GDScript files are already properly formatted!

              📊 **Summary:**
              - Total files checked: ${totalFiles}
              - Files needing formatting: 0

              🎉 No changes needed - code style is consistent.

              [View workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})`;
            }

            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: message
            });

      - name: Upload formatting artifacts
        if: failure()
        uses: actions/upload-artifact@v3
        with:
          name: gdformat-results
          path: |
            **/*.gd
          retention-days: 7

      - name: Workflow completion status
        run: |
          echo "🎉 GDScript formatting workflow completed!"
          echo ""
          echo "📋 Final Status:"
          if [[ "${{ steps.format-files.outputs.failed_files }}" != "0" ]]; then
            echo "❌ Some files failed to format"
            exit 1
          elif [[ "${{ steps.check-changes.outputs.has_changes }}" == "true" ]]; then
            echo "✅ Code formatted and changes pushed"
          else
            echo "✅ Code already properly formatted"
          fi