name: Sync SSH Keys
on:
  schedule:
    - cron: '0 * * * *' # Sync hourly
  workflow_dispatch: # Allow manual trigger
    inputs:
      environment:
        description: 'Target environment for syncing SSH keys'
        required: true
        default: 'production'
concurrency:
  group: sync-ssh-keys
  cancel-in-progress: false
permissions:
  contents: read
jobs:
  sync-keys:
    if: vars.SSH_HOSTNAME != ''
    name: Sync SSH keys to production
    runs-on: ubuntu-latest
    env:
      GH_TOKEN: ${{ github.token }}
    steps:
      - name: Get repository collaborators
        id: get-collaborators
        run: |
          echo "::group::Fetching collaborators"
          echo "::debug::Fetching collaborators for ${{ github.repository }}"

          # Get all collaborators with push access or higher
          collaborators=$(gh api \
            -H "Accept: application/vnd.github+json" \
            -H "X-GitHub-Api-Version: 2022-11-28" \
            "/repos/${{ github.repository }}/collaborators" \
            --jq '.[] | select(.permissions.push == true or .permissions.admin == true) | .login')

          if [ -z "$collaborators" ]; then
            echo "::error::No collaborators found with push/admin access"
            exit 1
          fi

          echo "::debug::Found collaborators:"
          echo "$collaborators"

          # Save to output
          echo "collaborators<<EOF" >> "$GITHUB_OUTPUT"
          echo "$collaborators" >> "$GITHUB_OUTPUT"
          echo "EOF" >> "$GITHUB_OUTPUT"

          collaborator_count=$(echo "$collaborators" | wc -l)
          echo "::debug::Total collaborators with push/admin access: $collaborator_count"
          echo "::endgroup::"
      - name: Fetch SSH keys for collaborators
        id: fetch-keys
        run: |
          echo "::group::Fetching SSH keys"

          # Initialize authorized_keys variable
          authorized_keys=""

          # Read collaborators and fetch their SSH keys
          while IFS= read -r username; do
            if [ -n "$username" ]; then
              echo "::debug::Fetching SSH keys for $username..."

              # Fetch SSH keys from GitHub
              keys=$(gh api \
                -H "Accept: application/vnd.github+json" \
                -H "X-GitHub-Api-Version: 2022-11-28" \
                "/users/$username/keys" \
                --jq '.[].key' 2>/dev/null || true)
              if [ -n "$keys" ]; then
                key_count=$(echo "$keys" | wc -l)
                echo "::debug::Found $key_count SSH key(s) for $username"

                # Add each key with command restriction
                while IFS= read -r key; do
                  if [ -n "$key" ]; then
                    authorized_keys+="command=\"docker system dial-stdio\",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty $key $username\n"
                  fi
                done <<< "$keys"
                authorized_keys+="\n"
              else
                echo "::warning::No SSH keys found for $username"
              fi
            fi
          done <<< "${{ steps.get-collaborators.outputs.collaborators }}"

          # Validate that we have at least one key
          if [ -z "$authorized_keys" ]; then
            echo "::error::No SSH keys found for any collaborators"
            exit 1
          fi

          echo "::debug::Generated authorized_keys file:"
          echo "$authorized_keys"

          # Count keys
          key_count=$(echo "$authorized_keys" | grep -c "^command=" || true)
          echo "::debug::Total SSH keys to sync: $key_count"

          # Save to output
          {
            echo "authorized_keys<<EOF"
            echo "$authorized_keys"
            echo "EOF"
          } >> "$GITHUB_OUTPUT"

          echo "::endgroup::"
      - name: Setup SSH
        uses: webfactory/ssh-agent@v0.9.1
        with:
          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
      - name: Pin known hosts
        run: |
          echo "::group::Pinning known hosts"
          echo "${{ vars.SSH_KNOWN_HOSTS }}" >> ~/.ssh/known_hosts
          echo "::debug::Known hosts updated:"
          cat ~/.ssh/known_hosts
          echo "::endgroup::"
      - name: Upload authorized_keys to remote host
        env:
          AUTHORIZED_KEYS: "${{ steps.fetch-keys.outputs.authorized_keys }}"
        run: |
          echo "::group::Uploading SSH keys to remote host"
          echo "::debug::Syncing SSH keys to ${{ vars.SSH_HOSTNAME }}"

          # Write directly to remote file
          echo "$AUTHORIZED_KEYS" | ssh "github@${{ vars.SSH_HOSTNAME }}" "sudo tee /home/collaborator/.ssh/authorized_keys > /dev/null"

          echo "::endgroup::"
      - name: Verify authorized_keys
        run: |
          echo "::group::Verifying authorized_keys on remote host"
          echo "::debug::Current authorized_keys on remote host:"
          ssh "github@${{ vars.SSH_HOSTNAME }}" "sudo cat /home/collaborator/.ssh/authorized_keys"

          remote_key_count=$(ssh "github@${{ vars.SSH_HOSTNAME }}" "sudo grep -c '^command=' /home/collaborator/.ssh/authorized_keys" || true)
          echo "::notice::✓ Synced $remote_key_count SSH keys to ${{ vars.SSH_HOSTNAME }}"
          echo "::endgroup::"
