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

DEFAULT_CLAUDE_MODEL="claude-sonnet-4-6"
DEFAULT_CODEX_PROFILE="vibediary"
DEFAULT_CODEX_WORKDIR="/tmp"

SKIP_CLAUDE=false
SKIP_CLAUDE_VSCODE=false
SKIP_CODEX=false
SKIP_CODEX_VSCODE=false
SKIP_OPENCLAW=false

CLAUDE_MODEL="$DEFAULT_CLAUDE_MODEL"
CODEX_PROFILE="${TRUSTAPI_SETUP_CODEX_PROFILE:-$DEFAULT_CODEX_PROFILE}"
CODEX_WORKDIR="$DEFAULT_CODEX_WORKDIR"
OPENCLAW_PROVIDER="${TRUSTAPI_SETUP_PROVIDER_ID:-}"
CLAUDE_SETTINGS="$HOME/.claude/settings.json"
CODEX_CONFIG="$HOME/.codex/config.toml"

usage() {
  cat <<'EOF'
Usage: verify.sh [OPTIONS]

Read-only verification for the VibeDiary mirror of TrustAPI Setup.

Options:
  --skip-claude           Skip Claude Code CLI verification
  --skip-claude-vscode    Skip Claude Code VS Code verification
  --skip-codex            Skip Codex CLI verification
  --skip-codex-vscode     Skip Codex VS Code verification
  --skip-openclaw         Skip OpenClaw verification
  --claude-model MODEL    Claude model for the HTTP smoke test
  --codex-profile NAME    Codex profile to run
  --codex-workdir DIR     Work directory for codex exec
  -h, --help              Show help
EOF
}

info() {
  printf '[INFO] %s\n' "$*"
}

die() {
  printf '[ERROR] %s\n' "$*" >&2
  exit 1
}

trim_file() {
  tr -d '\r' < "$1" | awk 'NF { line=$0 } END { print line }'
}

parse_args() {
  while [[ $# -gt 0 ]]; do
    case "$1" in
      --skip-claude)
        SKIP_CLAUDE=true
        shift
        ;;
      --skip-claude-vscode)
        SKIP_CLAUDE_VSCODE=true
        shift
        ;;
      --skip-codex)
        SKIP_CODEX=true
        shift
        ;;
      --skip-codex-vscode)
        SKIP_CODEX_VSCODE=true
        shift
        ;;
      --skip-openclaw)
        SKIP_OPENCLAW=true
        shift
        ;;
      --claude-model)
        [[ -n "${2:-}" ]] || die "missing value for --claude-model"
        CLAUDE_MODEL="$2"
        shift 2
        ;;
      --codex-profile)
        [[ -n "${2:-}" ]] || die "missing value for --codex-profile"
        CODEX_PROFILE="$2"
        shift 2
        ;;
      --codex-workdir)
        [[ -n "${2:-}" ]] || die "missing value for --codex-workdir"
        CODEX_WORKDIR="$2"
        shift 2
        ;;
      -h|--help)
        usage
        exit 0
        ;;
      *)
        die "unknown option: $1"
        ;;
    esac
  done
}

require_command() {
  command -v "$1" >/dev/null 2>&1 || die "$1 not found"
}

verify_claude() {
  local response
  require_command curl
  require_command claude
  [[ -n "${ANTHROPIC_BASE_URL:-}" ]] || die "ANTHROPIC_BASE_URL is not set"
  [[ -n "${ANTHROPIC_API_KEY:-}" ]] || die "ANTHROPIC_API_KEY is not set"

  info "verifying Claude HTTP contract via $ANTHROPIC_BASE_URL/v1/messages"
  response="$(curl -fsS "$ANTHROPIC_BASE_URL/v1/messages" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "content-type: application/json" \
    -d "{\"model\":\"$CLAUDE_MODEL\",\"max_tokens\":8,\"messages\":[{\"role\":\"user\",\"content\":\"Reply with exactly OK\"}]}")"
  printf '%s\n' "$response" | grep -q 'OK' || die "Claude HTTP smoke did not contain OK"

  info "verifying Claude CLI"
  [[ "$(claude --print "Reply with exactly OK" | tr -d '\r' | tail -n 1)" == "OK" ]] || die "Claude CLI smoke failed"
}

verify_claude_vscode() {
  [[ -f "$CLAUDE_SETTINGS" ]] || die "Claude VS Code settings not found: $CLAUDE_SETTINGS"
  python3 - "$CLAUDE_SETTINGS" <<'PY'
import json
import pathlib
import sys

path = pathlib.Path(sys.argv[1])
data = json.loads(path.read_text(encoding="utf-8"))
env = data.get("env")
if not isinstance(env, dict):
    raise SystemExit(1)
if not env.get("ANTHROPIC_BASE_URL"):
    raise SystemExit(1)
if not env.get("ANTHROPIC_API_KEY"):
    raise SystemExit(1)
PY
  info "verifying Claude VS Code env block"
}

verify_codex() {
  local output_file
  require_command codex
  mkdir -p "$CODEX_WORKDIR"
  output_file="$(mktemp)"

  info "verifying Codex profile $CODEX_PROFILE"
  codex exec \
    --profile "$CODEX_PROFILE" \
    --skip-git-repo-check \
    --ephemeral \
    -C "$CODEX_WORKDIR" \
    --output-last-message "$output_file" \
    "Reply with exactly OK." >/dev/null

  [[ "$(trim_file "$output_file")" == "OK" ]] || die "Codex smoke failed"
  rm -f "$output_file"
}

verify_codex_vscode() {
  [[ -f "$CODEX_CONFIG" ]] || die "Codex config not found: $CODEX_CONFIG"
  grep -Fq "[profiles.$CODEX_PROFILE]" "$CODEX_CONFIG" || die "Codex profile $CODEX_PROFILE missing from $CODEX_CONFIG"
  info "verifying Codex VS Code shared config"
}

verify_openclaw() {
  local provider_id
  require_command openclaw
  provider_id="${OPENCLAW_PROVIDER:-$CODEX_PROFILE}"
  [[ -n "$provider_id" ]] || die "OpenClaw provider id is empty"
  [[ -n "$(openclaw config get "models.providers.${provider_id}.baseUrl")" ]] || die "OpenClaw provider $provider_id is missing baseUrl"
  info "verifying OpenClaw provider $provider_id"
}

main() {
  parse_args "$@"
  [[ "$SKIP_CLAUDE" == false || "$SKIP_CLAUDE_VSCODE" == false || "$SKIP_CODEX" == false || "$SKIP_CODEX_VSCODE" == false || "$SKIP_OPENCLAW" == false ]] || die "cannot skip every verification target"

  [[ "$SKIP_CLAUDE" == true ]] || verify_claude
  [[ "$SKIP_CLAUDE_VSCODE" == true ]] || verify_claude_vscode
  [[ "$SKIP_CODEX" == true ]] || verify_codex
  [[ "$SKIP_CODEX_VSCODE" == true ]] || verify_codex_vscode
  [[ "$SKIP_OPENCLAW" == true ]] || verify_openclaw

  info "verification passed"
}

main "$@"
