name: Update doc DB

permissions:
  contents: write
  pull-requests: write

on:
  workflow_dispatch:
    inputs:
      python-version:
        description: Target python version to generate doc db for
        type: string
        default: "3.14.3"
      base-ref:
        description: Base branch to create the update branch from
        type: string
        default: "main"

defaults:
  run:
    shell: bash

jobs:
  generate:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os:
          - ubuntu-latest
          - windows-latest
          - macos-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false
          sparse-checkout: |
            crates/doc

      - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
        with:
          python-version: ${{ inputs.python-version }}

      - name: Generate docs
        run: python crates/doc/generate.py

      - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
        with:
          name: doc-db-${{ inputs.python-version }}-${{ matrix.os }}
          path: "crates/doc/generated/*.json"
          if-no-files-found: error
          retention-days: 7
          overwrite: true

  merge:
    runs-on: ubuntu-latest
    needs: generate
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: true
          ref: ${{ inputs.base-ref }}
          token: ${{ secrets.AUTO_COMMIT_PAT }}

      - name: Create update branch
        env:
          PYTHON_VERSION: ${{ inputs.python-version }}
        run: git switch -c "update-doc-${PYTHON_VERSION}"

      - name: Download generated doc DBs
        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
        with:
          pattern: "doc-db-${{ inputs.python-version }}-**"
          path: crates/doc/generated/
          merge-multiple: true

      - name: Transform JSON
        env:
          PYTHON_VERSION: ${{ inputs.python-version }}
        run: |
          # Merge all artifacts
          jq -s "add" --sort-keys crates/doc/generated/*.json > crates/doc/generated/merged.json

          # Format merged json for the phf macro
          jq -r 'to_entries[] | "    \(.key | @json) => \(.value | @json),"' crates/doc/generated/merged.json > crates/doc/generated/raw_entries.txt

          OUTPUT_FILE='crates/doc/src/data.inc.rs'

          echo -n '' > $OUTPUT_FILE

          echo '// This file was auto-generated by `.github/workflows/update-doc-db.yml`.' >> $OUTPUT_FILE
          echo "// CPython version: ${PYTHON_VERSION}" >> $OUTPUT_FILE
          echo '// spell-checker: disable' >> $OUTPUT_FILE

          echo '' >> $OUTPUT_FILE

          echo "pub static DB: phf::Map<&'static str, &'static str> = phf::phf_map! {" >> $OUTPUT_FILE
          cat crates/doc/generated/raw_entries.txt >> $OUTPUT_FILE
          echo '};' >> $OUTPUT_FILE

      - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
        with:
          name: doc-db-${{ inputs.python-version }}
          path: "crates/doc/src/data.inc.rs"
          if-no-files-found: error
          retention-days: 7
          overwrite: true

      - name: Commit, push and create PR
        env:
          GH_TOKEN: ${{ secrets.AUTO_COMMIT_PAT }}
          PYTHON_VERSION: ${{ inputs.python-version }}
          BASE_REF: ${{ inputs.base-ref }}
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          if [ -n "$(git status --porcelain)" ]; then
            git add crates/doc/src/data.inc.rs
            git commit -m "Update doc DB for CPython ${PYTHON_VERSION}"
            git push -u origin HEAD
            gh pr create \
              --base "${BASE_REF}" \
              --title "Update doc DB for CPython ${PYTHON_VERSION}" \
              --body "Auto-generated by update-doc-db workflow."
          fi
