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

BASE_URL="${CODELOGICIAN_LITE_URL:-https://api.imandra.ai/v1beta1/reasoners/codelogician-lite}"

# --- BEGIN SPEC (auto-generated, do not edit manually) ---
SPEC='{"__version__":"2.1.0","eval":{"check":{"accepts_iml":true,"args":[{"name":"file","required":false,"type":"TEXT"}],"options":[{"name":"with_vgs","required":false,"type":"BOOLEAN","flag":"--with-vgs"},{"name":"with_decomps","required":false,"type":"BOOLEAN","flag":"--with-decomps"},{"name":"json","required":false,"type":"BOOLEAN","flag":"--json"}],"help":"Evaluate an IML file without VG and decomp."},"list-vg":{"accepts_iml":true,"args":[{"name":"file","required":false,"type":"TEXT"}],"options":[{"name":"json","required":false,"type":"BOOLEAN","flag":"--json"}],"help":"List verification goals specified by `verify` or `instance` commands in an IML file."},"check-vg":{"accepts_iml":true,"args":[{"name":"file","required":false,"type":"TEXT"}],"options":[{"name":"index","required":false,"type":"INTEGER","flag":"--index"},{"name":"check_all","required":false,"type":"BOOLEAN","flag":"--check-all"},{"name":"json","required":false,"type":"BOOLEAN","flag":"--json"}],"help":"Check verification goals specified by `verify` or `instance` commands in an IML file."},"list-decomp":{"accepts_iml":true,"args":[{"name":"file","required":false,"type":"TEXT"}],"options":[{"name":"json","required":false,"type":"BOOLEAN","flag":"--json"}],"help":"List decomp requests in an IML file."},"check-decomp":{"accepts_iml":true,"args":[{"name":"file","required":false,"type":"TEXT"}],"options":[{"name":"index","required":false,"type":"INTEGER","flag":"--index"},{"name":"check_all","required":false,"type":"BOOLEAN","flag":"--check-all"},{"name":"json","required":false,"type":"BOOLEAN","flag":"--json"}],"help":"Check decomp requests in an IML file."},"gen-test":{"accepts_iml":true,"args":[{"name":"iml_path","required":true,"type":"TEXT"}],"options":[{"name":"function","required":true,"type":"TEXT","flag":"-f"},{"name":"lang","required":true,"type":"TEXT","flag":"-l"},{"name":"output","required":false,"type":"TEXT","flag":"-o"}],"help":"Generate test cases in Python / TypeScript from region decomp in IML."}},"doc":{"contents":{"accepts_iml":false,"args":[],"options":[],"help":"List the contents of the available documentation"},"prompt":{"accepts_iml":false,"args":[],"options":[],"help":"Generate a prompt to teach LLMs/Agents how to use ImandraX"},"dump":{"accepts_iml":false,"args":[{"name":"dir_path","required":true,"type":"PATH"}],"options":[],"help":"Dump IML overview and API reference to markdown files"},"search":{"accepts_iml":false,"args":[{"name":"query","required":true,"type":"TEXT"},{"name":"topic","required":false,"type":"TEXT"}],"options":[],"help":"Search the entire directory"},"view":{"accepts_iml":false,"args":[{"name":"desc","required":true,"type":"TEXT"}],"options":[],"help":"View a specific chapter or topic in documentation"},"ref":{"type":"group","commands":{"summary":{"accepts_iml":false,"args":[],"options":[],"help":"Provide an overview of the available modules"},"view":{"accepts_iml":false,"args":[{"name":"module","required":false,"type":"TEXT"}],"options":[],"help":"List IML API reference entries (optionally filtered by module)"}}}}}'
# --- END SPEC ---

CL_CLI_VERSION=$(jq -r '.__version__' <<<"$SPEC")
UPDATE_CHECK_URL="https://storage.googleapis.com/imandra-dev-codelogician-releases/codelogician-lite-shell/version.txt"
UPDATE_CHECK_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/codelogician"
UPDATE_CHECK_FILE="$UPDATE_CHECK_DIR/update-check"
UPDATE_CHECK_INTERVAL=86400  # 24 hours

# Warn if a newer version is available.
# Usage: check_for_update [--force]
#   --force: always fetch from cloud (used by --version)
#   default: fetch only if cache is stale (>24h)
check_for_update() {
  local force="${1:-}"
  local cloud_version=""

  if [ "$force" != "--force" ]; then
    # Use cached result if fresh
    if [ -f "$UPDATE_CHECK_FILE" ]; then
      local last_check
      last_check=$(head -1 "$UPDATE_CHECK_FILE" 2>/dev/null) || true
      local now
      now=$(date +%s)
      if [ -n "$last_check" ] && [ $((now - last_check)) -lt $UPDATE_CHECK_INTERVAL ]; then
        cloud_version=$(tail -1 "$UPDATE_CHECK_FILE" 2>/dev/null) || true
        if [ -n "$cloud_version" ] && [ "$cloud_version" != "$CL_CLI_VERSION" ]; then
          echo "Warning: codelogician $cloud_version is available. Update with: curl -fsSL codelogician.dev/cl-lite-shell/install.sh | sh" >&2
        fi
        return
      fi
    fi
  fi

  # Fetch from cloud
  cloud_version=$(curl -s --max-time 2 "$UPDATE_CHECK_URL" 2>/dev/null | tr -d '[:space:]') || true
  if [ -n "$cloud_version" ] && [[ "$cloud_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+ ]]; then
    mkdir -p "$UPDATE_CHECK_DIR" 2>/dev/null || true
    printf '%s\n%s\n' "$(date +%s)" "$cloud_version" > "$UPDATE_CHECK_FILE" 2>/dev/null || true
    if [ "$cloud_version" != "$CL_CLI_VERSION" ]; then
      echo "Warning: codelogician $cloud_version is available. Update with: curl -fsSL codelogician.dev/cl-lite-shell/install.sh | sh" >&2
    fi
  fi
}

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

[[ "${1:-}" == "--help" || "${1:-}" == "-h" ]] && usage 0
if [[ "${1:-}" == "--version" || "${1:-}" == "-v" ]]; then
  echo "codelogician-lite-shell $CL_CLI_VERSION"
  check_for_update --force
  exit 0
fi
[ $# -lt 2 ] && usage

# Periodic update check (cached)
check_for_update

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" >/dev/null 2>&1
  else
    jq -e --arg c "$command" --arg s "$sub" \
      '.[$c][$s].accepts_iml' <<<"$SPEC" >/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" >/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 [[ "$arg" == *.iml ]]; then
      if [ -n "$iml_file" ]; then
        echo "Error: codelogician-lite only supports single-file. Use full version of codelogician for multi-file support." >&2
        exit 1
      fi
      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

# Check for API key
api_key="${IMANDRA_UNI_KEY:-}"
if [ -z "$api_key" ]; then
  echo "Warning: IMANDRA_UNI_KEY environment variable is not set" >&2
  echo "Please set it with: export IMANDRA_UNI_KEY=<your-key>" >&2
  exit 1
fi

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

# Check if the server is reachable
http_code=$(curl -s --max-time 3 -o /dev/null -w '%{http_code}' -H "Authorization: Bearer ${IMANDRA_UNI_KEY:-}" "$BASE_URL/eval" 2>/dev/null) || true
if [ "$http_code" = "000" ] || [ "$http_code" = "404" ]; then
  echo "Error: server is not running at $BASE_URL" >&2
  exit 1
fi

response=$(curl -s --max-time 120 -X POST "$BASE_URL/eval" \
  -H "Authorization: Bearer ${IMANDRA_UNI_KEY:-}" \
  -H "Content-Type: application/json" \
  -d "$payload")
curl_exit=$?
if [ "$curl_exit" -ne 0 ]; then
  echo "Error: API request failed (curl exit code $curl_exit)" >&2
  exit 1
fi

# 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; exit 1; }
