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

API_BASE="${API_BASE:-http://localhost:5202/api}"
AUTH_TOKEN="${AUTH_TOKEN:-}"
CURL_TIMEOUT="${CURL_TIMEOUT:-15}"
CONNECT_TIMEOUT="${CONNECT_TIMEOUT:-3}"

TMP_DIR="$(mktemp -d)"
trap 'rm -rf "$TMP_DIR"' EXIT

note() {
  printf '%s\n' "$*"
}

fail() {
  printf 'ERROR: %s\n' "$*" >&2
  exit 1
}

json_get() {
  local file="$1"
  local path="$2"
  python3 - "$file" "$path" <<'PY'
import json
import sys

file_path, path = sys.argv[1], sys.argv[2]
with open(file_path, 'r', encoding='utf-8') as fh:
    data = json.load(fh)

value = data
for part in path.split('.'):
    if isinstance(value, dict) and part in value:
        value = value[part]
    else:
        raise KeyError(path)

if value is None:
    print('null')
elif isinstance(value, bool):
    print('true' if value else 'false')
elif isinstance(value, (dict, list)):
    print(json.dumps(value, separators=(',', ':')))
else:
    print(value)
PY
}

validate_json() {
  local file="$1"
  if ! python3 - "$file" <<'PY'
import json
import sys
with open(sys.argv[1], 'r', encoding='utf-8') as fh:
    json.load(fh)
PY
  then
    printf 'Raw response body:\n' >&2
    cat "$file" >&2
    fail "Malformed JSON returned by API."
  fi
}

request_json() {
  local name="$1"
  local url="$2"
  local body_file="$3"
  shift 3
  local -a headers=("$@")
  local err_file="$TMP_DIR/${name}.curl.err"
  local status_file="$TMP_DIR/${name}.status"
  : >"$err_file"

  set +e
  curl -fsS \
    --connect-timeout "$CONNECT_TIMEOUT" \
    --max-time "$CURL_TIMEOUT" \
    -H 'Accept: application/json' \
    "${headers[@]}" \
    -o "$body_file" \
    -w '%{http_code}' \
    "$url" >"$status_file" 2>"$err_file"
  local curl_exit=$?
  set -e

  if [[ $curl_exit -eq 0 ]]; then
    validate_json "$body_file"
    return 0
  fi
  local status='000'
  if [[ -s "$status_file" ]]; then
    status="$(tr -d '\r\n' <"$status_file")"
  fi

  case "$curl_exit:$status" in
    7:*|28:*|52:*|56:*|6:*)
      printf 'curl: %s\n' "$(tr -d '\r' <"$err_file")" >&2
      fail "Cannot reach ${url}. Start the API from JobTrackerApi/ with 'dotnet run' and verify it is listening on ${API_BASE%/api}."
      ;;
    22:401|22:403)
      note "${name}: auth required."
      note "Hint: export AUTH_TOKEN with an admin bearer token from POST ${API_BASE}/auth/login before rerunning this preflight."
      return 22
      ;;
    22:*)
      local diag_body="$TMP_DIR/${name}.diag.body"
      local diag_status="$TMP_DIR/${name}.diag.status"
      local diag_err="$TMP_DIR/${name}.diag.err"
      curl -sS \
        --connect-timeout "$CONNECT_TIMEOUT" \
        --max-time "$CURL_TIMEOUT" \
        -H 'Accept: application/json' \
        "${headers[@]}" \
        -o "$diag_body" \
        -w '%{http_code}' \
        "$url" >"$diag_status" 2>"$diag_err" || true
      local http_status="$(tr -d '\r\n' <"$diag_status")"
      printf 'curl: %s\n' "$(tr -d '\r' <"$err_file")" >&2
      if [[ -s "$diag_body" ]]; then
        printf 'Response body:\n' >&2
        cat "$diag_body" >&2
        printf '\n' >&2
      fi
      fail "${name} probe failed with HTTP ${http_status:-unknown}."
      ;;
    *)
      printf 'curl: %s\n' "$(tr -d '\r' <"$err_file")" >&2
      fail "${name} probe failed with curl exit ${curl_exit}."
      ;;
  esac
}

auth_config_body="$TMP_DIR/auth-config.json"
request_json "auth config" "$API_BASE/auth/config" "$auth_config_body"

require_auth="$(json_get "$auth_config_body" 'requireAuth')"
google_enabled="$(json_get "$auth_config_body" 'googleEnabled')"
local_enabled="$(json_get "$auth_config_body" 'localEnabled')"
allow_registration="$(json_get "$auth_config_body" 'allowRegistration')"

note "Preflight target: ${API_BASE}"
note "cors.requiredOriginPair=UI http://localhost:3000 -> API http://localhost:5202/api"
note "auth.requireAuth=${require_auth}"
note "auth.localEnabled=${local_enabled}"
note "auth.googleEnabled=${google_enabled}"
note "auth.allowRegistration=${allow_registration}"

system_body="$TMP_DIR/admin-system.json"
declare -a auth_headers=()
if [[ -n "$AUTH_TOKEN" ]]; then
  auth_headers+=(-H "Authorization: Bearer ${AUTH_TOKEN}")
fi

if request_json "admin system" "$API_BASE/admin/system" "$system_body" "${auth_headers[@]}"; then
  db_provider="$(json_get "$system_body" 'database.provider')"
  db_configured="$(json_get "$system_body" 'database.looksConfigured')"
  db_connect="$(json_get "$system_body" 'database.canConnect')"
  db_target="$(json_get "$system_body" 'database.target')"
  db_warning="$(json_get "$system_body" 'database.warning')"
  auth_required_runtime="$(json_get "$system_body" 'auth.required')"
  gmail_configured="$(json_get "$system_body" 'auth.gmailConfigured')"
  ai_healthy="$(json_get "$system_body" 'ai.healthy')"
  ai_model="$(json_get "$system_body" 'ai.model')"
  ai_last_error="$(json_get "$system_body" 'ai.lastError')"

  note "db.provider=${db_provider}"
  note "db.looksConfigured=${db_configured}"
  note "db.canConnect=${db_connect}"
  note "db.target=${db_target}"
  note "db.warning=${db_warning}"
  note "auth.runtimeRequired=${auth_required_runtime}"
  note "gmailConfigured=${gmail_configured}"
  note "ai.healthy=${ai_healthy}"
  note "ai.model=${ai_model}"
  note "ai.lastError=${ai_last_error}"

  if [[ "$db_connect" != "true" ]]; then
    fail "Database is not connectable according to /admin/system."
  fi

  note "Preflight passed."
  exit 0
fi

note "db.provider=unknown"
note "db.looksConfigured=unknown"
note "db.canConnect=unknown"
note "db.target=unknown"
note "db.warning=admin token required to inspect database status"
note "gmailConfigured=unknown"
note "ai.healthy=unknown"
note "ai.model=unknown"
note "ai.lastError=unknown"
note "Preflight partially passed: anonymous auth config is reachable, but admin/system requires an admin bearer token for DB/Gmail/AI details."
