#!/usr/bin/env bash
set -euo pipefail

# Read-only wrapper for the GitHub CLI.
# Blocks all write/delete/modify commands; passes read-only commands through to gh.
# See references/allowed-commands.md for the full list.

# --- Extract command trajectory (non-flag arguments) ---
args=("$@")
cmd1="" cmd2="" cmd3=""

for arg in "$@"; do
  case "$arg" in
    -*) continue ;;   # skip flags
  esac
  if [[ -z "$cmd1" ]]; then
    cmd1="$arg"
  elif [[ -z "$cmd2" ]]; then
    cmd2="$arg"
  elif [[ -z "$cmd3" ]]; then
    cmd3="$arg"
    break
  fi
done

# --- Always-allowed: no args, help, version ---
if [[ ${#args[@]} -eq 0 ]]; then
  exec gh "$@"
fi

# --version as the only meaningful arg (might be preceded by flags)
for arg in "$@"; do
  if [[ "$arg" == "--version" ]]; then
    exec gh "$@"
  fi
done

# --help/-h anywhere → allow
for arg in "$@"; do
  if [[ "$arg" == "--help" || "$arg" == "-h" ]]; then
    exec gh "$@"
  fi
done

# `gh help` subcommand
case "$cmd1" in
  help) exec gh "$@" ;;
esac

# --- Command allowlist ---
case "$cmd1" in
  # Bare commands (no subcommands)
  browse|completion|status|licenses)
    exec gh "$@"
    ;;

  # auth
  auth)
    case "$cmd2" in
      status) exec gh "$@" ;;
      *)      echo "gh-ro: blocked trajectory: auth $cmd2" >&2; exit 1 ;;
    esac
    ;;

  # issue
  issue)
    case "$cmd2" in
      list|status|view) exec gh "$@" ;;
      *)                echo "gh-ro: blocked trajectory: issue $cmd2" >&2; exit 1 ;;
    esac
    ;;

  # pr
  pr)
    case "$cmd2" in
      checks|diff|list|status|view) exec gh "$@" ;;
      *)                             echo "gh-ro: blocked trajectory: pr $cmd2" >&2; exit 1 ;;
    esac
    ;;

  # repo (2-deep: repo gitignore/license)
  repo)
    case "$cmd2" in
      list|view) exec gh "$@" ;;
      gitignore)
        case "$cmd3" in
          list|view) exec gh "$@" ;;
          *)         echo "gh-ro: blocked trajectory: repo gitignore $cmd3" >&2; exit 1 ;;
        esac
        ;;
      license)
        case "$cmd3" in
          list|view) exec gh "$@" ;;
          *)         echo "gh-ro: blocked trajectory: repo license $cmd3" >&2; exit 1 ;;
        esac
        ;;
      *) echo "gh-ro: blocked trajectory: repo $cmd2" >&2; exit 1 ;;
    esac
    ;;

  # run
  run)
    case "$cmd2" in
      list|view|watch) exec gh "$@" ;;
      *)               echo "gh-ro: blocked trajectory: run $cmd2" >&2; exit 1 ;;
    esac
    ;;

  # workflow
  workflow)
    case "$cmd2" in
      list|view) exec gh "$@" ;;
      *)          echo "gh-ro: blocked trajectory: workflow $cmd2" >&2; exit 1 ;;
    esac
    ;;

  # search (all subcommands are read-only)
  search)
    case "$cmd2" in
      code|commits|issues|prs|repos) exec gh "$@" ;;
      *)                              echo "gh-ro: blocked trajectory: search $cmd2" >&2; exit 1 ;;
    esac
    ;;

  # codespace
  codespace)
    case "$cmd2" in
      list|view|logs) exec gh "$@" ;;
      *)               echo "gh-ro: blocked trajectory: codespace $cmd2" >&2; exit 1 ;;
    esac
    ;;

  # gist
  gist)
    case "$cmd2" in
      list|view) exec gh "$@" ;;
      *)          echo "gh-ro: blocked trajectory: gist $cmd2" >&2; exit 1 ;;
    esac
    ;;

  # project
  project)
    case "$cmd2" in
      field-list|item-list|list|view) exec gh "$@" ;;
      *)                               echo "gh-ro: blocked trajectory: project $cmd2" >&2; exit 1 ;;
    esac
    ;;

  # release
  release)
    case "$cmd2" in
      list|view) exec gh "$@" ;;
      *)          echo "gh-ro: blocked trajectory: release $cmd2" >&2; exit 1 ;;
    esac
    ;;

  # cache
  cache)
    case "$cmd2" in
      list) exec gh "$@" ;;
      *)     echo "gh-ro: blocked trajectory: cache $cmd2" >&2; exit 1 ;;
    esac
    ;;

  # org
  org)
    case "$cmd2" in
      list) exec gh "$@" ;;
      *)     echo "gh-ro: blocked trajectory: org $cmd2" >&2; exit 1 ;;
    esac
    ;;

  # label
  label)
    case "$cmd2" in
      list) exec gh "$@" ;;
      *)     echo "gh-ro: blocked trajectory: label $cmd2" >&2; exit 1 ;;
    esac
    ;;

  # ruleset
  ruleset)
    case "$cmd2" in
      check|list|view) exec gh "$@" ;;
      *)                echo "gh-ro: blocked trajectory: ruleset $cmd2" >&2; exit 1 ;;
    esac
    ;;

  # secret
  secret)
    case "$cmd2" in
      list) exec gh "$@" ;;
      *)     echo "gh-ro: blocked trajectory: secret $cmd2" >&2; exit 1 ;;
    esac
    ;;

  # variable
  variable)
    case "$cmd2" in
      get|list) exec gh "$@" ;;
      *)          echo "gh-ro: blocked trajectory: variable $cmd2" >&2; exit 1 ;;
    esac
    ;;

  # attestation
  attestation)
    case "$cmd2" in
      trusted-root|verify) exec gh "$@" ;;
      *)                     echo "gh-ro: blocked trajectory: attestation $cmd2" >&2; exit 1 ;;
    esac
    ;;

  # gpg-key
  gpg-key)
    case "$cmd2" in
      list) exec gh "$@" ;;
      *)     echo "gh-ro: blocked trajectory: gpg-key $cmd2" >&2; exit 1 ;;
    esac
    ;;

  # ssh-key
  ssh-key)
    case "$cmd2" in
      list) exec gh "$@" ;;
      *)     echo "gh-ro: blocked trajectory: ssh-key $cmd2" >&2; exit 1 ;;
    esac
    ;;

  # agent-task
  agent-task)
    case "$cmd2" in
      list|view) exec gh "$@" ;;
      *)           echo "gh-ro: blocked trajectory: agent-task $cmd2" >&2; exit 1 ;;
    esac
    ;;

  # alias
  alias)
    case "$cmd2" in
      list) exec gh "$@" ;;
      *)     echo "gh-ro: blocked trajectory: alias $cmd2" >&2; exit 1 ;;
    esac
    ;;

  # extension
  extension)
    case "$cmd2" in
      list|search) exec gh "$@" ;;
      *)            echo "gh-ro: blocked trajectory: extension $cmd2" >&2; exit 1 ;;
    esac
    ;;

  # config
  config)
    case "$cmd2" in
      get|list) exec gh "$@" ;;
      *)          echo "gh-ro: blocked trajectory: config $cmd2" >&2; exit 1 ;;
    esac
    ;;

  # Entirely blocked commands
  api|copilot|preview|skill)
    echo "gh-ro: $cmd1 is entirely blocked (no read-only usage)" >&2
    exit 1
    ;;

  # Unknown command — reject by default
  *)
    echo "gh-ro: unknown or blocked command: $cmd1" >&2
    echo "If this is a valid read-only gh command, add it to the allowlist." >&2
    echo "See references/allowed-commands.md for the full reference." >&2
    exit 1
    ;;
esac