name: Run Menu

on:
  workflow_dispatch:
    inputs:
      action_type:
        description: 'Action to perform'
        required: true
        default: 'render'
        type: choice
        options:
          - render
          - topdf
          - todocx
          - freeze
          - custom-update
          - collectExternalReferences
      repository:
        description: 'Repository'
        required: false
      branch:
        description: 'Branch'
        required: false
      triggered_by:
        description: 'Triggered by'
        required: false
      freeze_label:
        description: 'Label for the snapshot (freeze action only). Leave empty to use the auto-generated version number.'
        required: false
        default: ''

jobs:
  build-and-deploy-spec:
    runs-on: ubuntu-latest
    permissions:
      contents: write   # Needed for pushing changes
      actions: write    # Needed to dispatch render-and-deploy.yml
    steps:
      - name: Checkout 🛎️
        uses: actions/checkout@v6
        with:
          persist-credentials: true  # The push step below authenticates with GITHUB_TOKEN

      - name: Set up Node.js
        uses: actions/setup-node@v6
        with:
          node-version: '24'

      - name: Extract output_path from JSON
        id: extract-output
        run: |
          OUTPUT_PATH=$(jq -r '.specs[0].output_path // "default/output"' specs.json)
          if [ "$OUTPUT_PATH" = "null" ] || [ -z "$OUTPUT_PATH" ]; then
            echo "Error: Unable to extract output_path from specs.json"
            exit 1
          fi
          echo "OUTPUT_PATH=$OUTPUT_PATH" >> $GITHUB_ENV

      - name: Install dependencies 🔧
        run: |
          echo "Installing dependencies..."
          npm install
          echo "Spec-Up-T version:"
          npm list spec-up-t || echo "spec-up-t not found"

      - name: Run selected script
        env:
          # freeze_label is free-form dispatch input. Bind it to an env var rather
          # than interpolating it into the shell command, so a label containing
          # shell metacharacters cannot inject commands into this step.
          FREEZE_LABEL_INPUT: ${{ github.event.inputs.freeze_label }}
        run: |
          case "${{ github.event.inputs.action_type }}" in
            render)
              # Rendering is handled by render-and-deploy.yml.
              # Dispatch that workflow to render and deploy to GitHub Pages.
              curl -s -X POST \
                -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
                -H "Accept: application/vnd.github+json" \
                "https://api.github.com/repos/${{ github.repository }}/actions/workflows/render-and-deploy.yml/dispatches" \
                -d "{\"ref\":\"${{ github.ref_name }}\"}"
              echo "render-and-deploy.yml dispatched"
              ;;
            topdf)
              npm run topdf
              ;;
            todocx)
              npm run todocx
              ;;
            freeze)
              # A fresh CI checkout has no docs/ (gitignored), so we must render
              # first to give freeze-spec-data.js the docs/index.html it needs.
              # freeze-spec-data.js then writes the snapshot to snapshots/,
              # which is tracked in git. The commit+push step below commits
              # snapshots/ to the main branch, which triggers
              # render-and-deploy.yml to deploy the full spec (including versions).
              npm run collectExternalReferences
              FREEZE_LABEL="$FREEZE_LABEL_INPUT" npm run freeze
              ;;
            custom-update)
              # --yes applies the printed plan. Actions has no prompt.
              # Do not pass --force-workflows here. A workflow that differs
              # from the boilerplate is kept. GITHUB_TOKEN cannot push
              # changes under .github/workflows/.
              npm run custom-update -- --yes
              ;;
            collectExternalReferences)
              npm run collectExternalReferences
              ;;
            *)
              echo "Unknown action_type: ${{ github.event.inputs.action_type }}"
              exit 1
              ;;
          esac

      - name: Commit and push changes
        if: success()
        run: |
          git config --global user.email "actions@github.com"
          git config --global user.name "GitHub Actions"
          
          # Add all changes
          git add .
          
          # Commit with appropriate message
          case "${{ github.event.inputs.action_type }}" in
            render)
              # render-and-deploy.yml already handles the commit/deploy; nothing to commit here.
              echo "Render dispatched to render-and-deploy.yml — no direct commit needed"
              ;;
            topdf)
              git commit -m "Export to PDF" || echo "No changes to commit"
              ;;
            todocx)
              git commit -m "Export to DOCX" || echo "No changes to commit"
              ;;
            collectExternalReferences)
              git commit -m "Collect external references" || echo "No changes to commit"
              ;;
            freeze)
              # snapshots/ is tracked in git and will be committed.
              # Note: a GITHUB_TOKEN push does NOT automatically trigger other workflows
              # (GitHub security restriction). render-and-deploy.yml is dispatched
              # explicitly in the "Deploy frozen snapshots to GitHub Pages" step below.
              git commit -m "Freeze specification" || echo "No changes to commit"
              ;;
            custom-update)
              git commit -m "Custom update: Copy files from spec-up-t" || echo "No changes to commit"
              ;;
            *)
              git commit -m "Update files: ${{ github.event.inputs.action_type }}" || echo "No changes to commit"
              ;;
          esac
          
          # Push changes
          git push https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git HEAD:${{ github.ref_name }}

      # After a freeze commit, render-and-deploy.yml must be dispatched explicitly.
      # GitHub blocks other workflow runs triggered by GITHUB_TOKEN pushes (security
      # restriction), so the push in "Commit and push changes" alone is not enough
      # to propagate the new snapshot to the gh-pages branch.
      # Dispatching render-and-deploy.yml here ensures:
      #   1. The full render pipeline runs (including snapshots/ → docs/versions/ sync).
      #   2. The updated docs/ (with the new frozen version) is deployed to gh-pages.
      - name: Deploy frozen snapshots to GitHub Pages
        if: success() && github.event.inputs.action_type == 'freeze'
        run: |
          curl -s -X POST \
            -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
            -H "Accept: application/vnd.github+json" \
            "https://api.github.com/repos/${{ github.repository }}/actions/workflows/render-and-deploy.yml/dispatches" \
            -d "{\"ref\":\"${{ github.ref_name }}\"}"
          echo "render-and-deploy.yml dispatched — frozen snapshots will be deployed to gh-pages"

      - name: Clean up
        if: always()
        run: |
          echo "Cleaning up..."
          rm -rf node_modules
