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

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SPEC_FILE="$SCRIPT_DIR/spec.json"
BASE_URL="${CODELOGICIAN_LITE_URL:-http://localhost:8080}"

if [ ! -f "$SPEC_FILE" ]; then
  echo "Error: spec.json not found at $SPEC_FILE" >&2
  exit 1
fi

usage() {
  echo "Usage: codelogician <eval|doc> <subcommand> [options] [file.iml]"
  exit "${1:-1}"
}

[[ "${1:-}" == "--help" || "${1:-}" == "-h" ]] && usage 0
[ $# -lt 2 ] && usage

command="$1"
shift

# Validate top-level command against spec
case "$command" in
  eval|doc) ;;
  *) echo "Error: unknown command '$command'" >&2; usage ;;
esac

# Determine if the subcommand accepts IML input using the spec.
# Walk one or two levels: "eval check" or "doc ref view".
accepts_iml() {
  local sub="$1" subsub="${2:-}"
  if [ -n "$subsub" ]; then
    jq -e --arg c "$command" --arg s "$sub" --arg ss "$subsub" \
      '.[$c][$s].commands[$ss].accepts_iml' "$SPEC_FILE" >/dev/null 2>&1
  else
    jq -e --arg c "$command" --arg s "$sub" \
      '.[$c][$s].accepts_iml' "$SPEC_FILE" >/dev/null 2>&1
  fi
}

# Peek at the subcommand(s) to decide about file handling
sub="$1"
subsub=""
if jq -e --arg c "$command" --arg s "$sub" '.[$c][$s].type == "group"' "$SPEC_FILE" >/dev/null 2>&1; then
  subsub="${2:-}"
fi

# Find and extract the .iml file argument — only if the subcommand accepts one
args=("$@")
iml_file=""
if accepts_iml "$sub" "$subsub" && [ ${#args[@]} -gt 0 ]; then
  remaining=()
  for arg in "${args[@]}"; do
    if [[ -z "$iml_file" && "$arg" == *.iml ]]; then
      if [ ! -f "$arg" ]; then
        echo "Error: file not found: $arg" >&2
        exit 1
      fi
      iml_file="$arg"
    else
      remaining+=("$arg")
    fi
  done
  args=("${remaining[@]+"${remaining[@]}"}")
fi

# Build the command string: "eval check --json" or "doc ref view int"
cl_command="$command${args[*]:+ ${args[*]}}"

# Read body: .iml file arg > stdin > empty
body=""
if [ -n "$iml_file" ]; then
  body=$(cat "$iml_file")
elif accepts_iml "$sub" "$subsub" && [ ! -t 0 ]; then
  body=$(cat)
fi

# Build JSON payload for the IU reasoner interface
cl_env='{"TYPER_USE_RICH": "0"}'
if [ -n "$body" ]; then
  payload=$(jq -n --arg cmd "$cl_command" --arg body "$body" --argjson env "$cl_env" \
    '{"input": ({"command": $cmd, "body": $body, "env": $env} | tojson)}')
else
  payload=$(jq -n --arg cmd "$cl_command" --argjson env "$cl_env" \
    '{"input": ({"command": $cmd, "env": $env} | tojson)}')
fi

# Check if the server is running
if ! curl -s --max-time 3 "$BASE_URL/health" > /dev/null 2>&1; then
  echo "Error: server is not running at $BASE_URL" >&2
  exit 1
fi

response=$(curl -s -X POST "$BASE_URL/eval" \
  -H "Content-Type: application/json" \
  -d "$payload")

# IU response: {"results": [...], "errors": [...], "artifacts": [...], "stats": {}}
results=$(echo "$response" | jq -r '.results[]' 2>/dev/null)
errors=$(echo "$response" | jq -r '.errors[]' 2>/dev/null)

[ -n "$results" ] && echo "$results"
[ -n "$errors" ] && echo "$errors" >&2

if [ -n "$errors" ]; then
  exit 1
fi
