#!/bin/bash
set -uo pipefail

WORKSPACE=""
PROMPT=""
TASK_SLUG=""
PROFILE=""
TIMEOUT=""
BACKEND=""
PURPOSE=""
INSPECT=0

if [[ "${1:-}" == "--help" ]]; then
  printf '%s\n' \
    'usage: model-test-fixture --purpose verification --backend <opencode|codex|north> --workspace <dir> --trust <prompt> --task-slug <slug> [--profile <codex-account>] [--timeout <seconds>] [--inspect]' \
    'routes: OpenCode deepseek-v4-flash-free; Codex gpt-5.3-codex-spark; North cohere/north-mini-code:free through canonical na.sh' \
    '--inspect validates pinned executables and prints command JSON without launching a model' \
    'no model, wrapper, engine, config, or fallback override is accepted'
  exit 0
fi

while [[ $# -gt 0 ]]; do
  case "$1" in
    --purpose) [[ $# -ge 2 ]] || { echo '{"ok":false,"detail":"--purpose requires a value"}' >&2; exit 2; }; PURPOSE="$2"; shift 2 ;;
    --backend) [[ $# -ge 2 ]] || { echo '{"ok":false,"detail":"--backend requires a value"}' >&2; exit 2; }; BACKEND="$2"; shift 2 ;;
    --workspace) [[ $# -ge 2 ]] || { echo '{"ok":false,"detail":"--workspace requires a value"}' >&2; exit 2; }; WORKSPACE="$2"; shift 2 ;;
    --trust) [[ $# -ge 2 ]] || { echo '{"ok":false,"detail":"--trust requires a value"}' >&2; exit 2; }; PROMPT="$2"; shift 2 ;;
    --task-slug) [[ $# -ge 2 ]] || { echo '{"ok":false,"detail":"--task-slug requires a value"}' >&2; exit 2; }; TASK_SLUG="$2"; shift 2 ;;
    --profile) [[ $# -ge 2 && -n "$2" ]] || { echo '{"ok":false,"detail":"--profile requires a value"}' >&2; exit 2; }; PROFILE="$2"; shift 2 ;;
    --timeout) [[ $# -ge 2 ]] || { echo '{"ok":false,"detail":"--timeout requires a value"}' >&2; exit 2; }; TIMEOUT="$2"; shift 2 ;;
    --inspect) INSPECT=1; shift ;;
    *) echo "{\"ok\":false,\"detail\":\"unknown flag: $1\"}" >&2; exit 2 ;;
  esac
done

[[ "$PURPOSE" == "verification" ]] || { echo '{"ok":false,"detail":"--purpose verification required"}' >&2; exit 2; }
case "$BACKEND" in
  opencode|codex|north) ;;
  "") echo '{"ok":false,"detail":"--backend required: opencode|codex|north"}' >&2; exit 2 ;;
  *) echo '{"ok":false,"detail":"backend is not an allowed fixture route"}' >&2; exit 2 ;;
esac
[[ -n "$WORKSPACE" && -d "$WORKSPACE" ]] || { echo '{"ok":false,"detail":"--workspace missing or not a dir"}' >&2; exit 2; }
[[ -n "$PROMPT" ]] || { echo '{"ok":false,"detail":"--trust (prompt) required"}' >&2; exit 2; }
[[ -n "$TASK_SLUG" ]] || { echo '{"ok":false,"detail":"--task-slug required"}' >&2; exit 2; }
if [[ -n "$TIMEOUT" && ! "$TIMEOUT" =~ ^[1-9][0-9]*$ ]]; then
  echo '{"ok":false,"detail":"--timeout must be a positive integer"}' >&2
  exit 2
fi
if [[ -n "$PROFILE" ]]; then
  [[ "$BACKEND" == "codex" ]] || { echo '{"ok":false,"detail":"--profile is supported only for the codex fixture"}' >&2; exit 2; }
  [[ "$PROFILE" =~ ^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$ ]] || { echo '{"ok":false,"detail":"--profile is not a valid codex account selector"}' >&2; exit 2; }
fi

PASSWD_ENTRY="$(/usr/bin/getent passwd "$(/usr/bin/id -u)")" || true
IFS=: read -r _ _ _ _ _ OWNER_HOME _ <<< "$PASSWD_ENTRY"
[[ "$OWNER_HOME" == /* && -d "$OWNER_HOME" ]] || { echo '{"ok":false,"detail":"owner home resolution failed"}' >&2; exit 3; }

SCRIPT_DIR="$(cd -- "${BASH_SOURCE[0]%/*}" && pwd -P)"
DEPLOY_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd -P)"
OPENCODE_WRAPPER="$SCRIPT_DIR/opencode.sh"
CODEX_WRAPPER="$SCRIPT_DIR/codex.sh"
NORTH_WRAPPER="$DEPLOY_ROOT/modules/workstation/claude/skills/north-orchestrator/na.sh"
OPENCODE_BIN="$OWNER_HOME/.claude/bin/opencode"
CODEX_BIN="$OWNER_HOME/.local/bin/cdx"
CLAUDE_BIN="$OWNER_HOME/.claude/bin/claude"

case "$BACKEND" in
  opencode) trusted_executables=("$OPENCODE_WRAPPER" "$OPENCODE_BIN") ;;
  codex) trusted_executables=("$CODEX_WRAPPER" "$CODEX_BIN") ;;
  north) trusted_executables=("$NORTH_WRAPPER" "$CLAUDE_BIN") ;;
esac
for executable in "${trusted_executables[@]}"; do
  [[ "$executable" == /* && -x "$executable" ]] || {
    printf '{"ok":false,"detail":"trusted executable missing: %s"}\n' "$executable" >&2
    exit 3
  }
done

unset \
  _OPENCODE_ENGINE_BIN _CODEX_ENGINE_BIN _CODEX_ENV _NA_CLAUDE_BIN \
  _NA_CCR_UP_BIN _NA_NORTH_ENV _NA_HEALTH_URL _NA_MODELS_URL \
  OPENCODE_CONFIG OPENCODE_CONFIG_DIR OPENCODE_CONFIG_CONTENT OPENCODE_MODEL \
  CODEX_HOME OPENAI_BASE_URL OPENAI_API_BASE \
  CLAUDE_CONFIG_DIR ANTHROPIC_BASE_URL ANTHROPIC_MODEL ANTHROPIC_SMALL_FAST_MODEL \
  ANTHROPIC_DEFAULT_OPUS_MODEL ANTHROPIC_DEFAULT_SONNET_MODEL ANTHROPIC_DEFAULT_HAIKU_MODEL \
  CLAUDE_CODE_USE_BEDROCK CLAUDE_CODE_USE_VERTEX ANTHROPIC_BEDROCK_BASE_URL ANTHROPIC_VERTEX_BASE_URL \
  CCR_PORT CCR_CMD CCR_UP_TIMEOUT CCR_LOCK_WAIT CCR_TMP_ROOT
export HOME="$OWNER_HOME"
export PATH="/usr/local/bin:/usr/bin:/bin:$OWNER_HOME/.local/bin:$OWNER_HOME/.claude/bin"

if [[ $INSPECT -eq 1 ]]; then
  case "$BACKEND" in
    opencode)
      wrapper="$OPENCODE_WRAPPER" engine="$OPENCODE_BIN" model="deepseek-v4-flash-free"
      engine_args=(run --model "$model" --dangerously-skip-permissions --dir "$WORKSPACE" "$PROMPT")
      ;;
    codex)
      wrapper="$CODEX_WRAPPER" engine="$CODEX_BIN" model="gpt-5.3-codex-spark"
      engine_args=()
      [[ -n "$PROFILE" ]] && engine_args+=("--profile=$PROFILE")
      engine_args+=(exec --json -C "$WORKSPACE" --skip-git-repo-check --model "$model" -c model_reasoning_effort=high "$PROMPT")
      ;;
    north)
      args=(--workspace "$WORKSPACE" --trust "$PROMPT" --task-slug "$TASK_SLUG" --claude-bin "$CLAUDE_BIN" --inspect)
      [[ -n "$TIMEOUT" ]] && args+=(--timeout "$TIMEOUT")
      exec /bin/bash "$NORTH_WRAPPER" "${args[@]}"
      ;;
  esac
  /usr/bin/python3 - "$BACKEND" "$wrapper" "$engine" "$model" "${engine_args[@]}" <<'PY'
import json
import sys

backend, wrapper, engine, model, *args = sys.argv[1:]
print(json.dumps({
    "ok": True,
    "purpose": "verification",
    "backend": backend,
    "wrapper": wrapper,
    "engine": engine,
    "model": model,
    "engine_args": args,
}, separators=(",", ":")))
PY
  exit 0
fi

case "$BACKEND" in
  opencode)
    export _OPENCODE_ENGINE_BIN="$OPENCODE_BIN"
    args=(--workspace "$WORKSPACE" --trust "$PROMPT" --task-slug "$TASK_SLUG" --model deepseek-v4-flash-free)
    [[ -n "$TIMEOUT" ]] && args+=(--timeout "$TIMEOUT")
    exec /bin/bash "$OPENCODE_WRAPPER" "${args[@]}"
    ;;
  codex)
    export _CODEX_ENGINE_BIN="$CODEX_BIN"
    args=(--workspace "$WORKSPACE" --trust "$PROMPT" --task-slug "$TASK_SLUG" --model gpt-5.3-codex-spark --permission-mode safe)
    [[ -n "$PROFILE" ]] && args+=(--profile "$PROFILE")
    [[ -n "$TIMEOUT" ]] && args+=(--timeout "$TIMEOUT")
    exec /bin/bash "$CODEX_WRAPPER" "${args[@]}"
    ;;
  north)
    args=(--workspace "$WORKSPACE" --trust "$PROMPT" --task-slug "$TASK_SLUG" --claude-bin "$CLAUDE_BIN")
    [[ -n "$TIMEOUT" ]] && args+=(--timeout "$TIMEOUT")
    exec /bin/bash "$NORTH_WRAPPER" "${args[@]}"
    ;;
esac
