#!/usr/bin/env bash
# proxmox-api -- Make authenticated Proxmox API calls
#
# Usage: proxmox-api METHOD PATH [CURL_ARGS...]
#
# Handles the ! in automation@pve!deploy safely (no bash history expansion).
# Config: proxmox.yaml (host, api_token_id), env file (PROXMOX_TOKEN_SECRET)
#
# Outputs JSON response on stdout.

set -euo pipefail

# ---------------------------------------------------------------------------
# Usage
# ---------------------------------------------------------------------------

usage() {
    cat <<'EOF'
Usage: proxmox-api METHOD PATH [CURL_ARGS...]

Make authenticated Proxmox API calls with proper token handling.

Arguments:
  METHOD        HTTP method (GET, POST, PUT, DELETE)
  PATH          API path (e.g., /nodes/pve/qemu)
  CURL_ARGS     Additional curl arguments (e.g., -d 'key=val')

Options:
  --json        Pretty-print JSON output
  --help, -h    Show this help

Environment:
  PROXMOX_TOKEN_SECRET    API token secret (from env file)

Config:
  proxmox.yaml            Proxmox host + api_token_id (auto-discovered)

Examples:
  proxmox-api GET /nodes/pve/qemu
  proxmox-api GET /nodes/pve/qemu/900/status/current --json
  proxmox-api POST /nodes/pve/qemu/900/status/stop
  proxmox-api GET /cluster/resources --json
EOF
    exit 0
}

if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then
    usage
fi

# ---------------------------------------------------------------------------
# Parse arguments
# ---------------------------------------------------------------------------

PRETTY=false
ARGS=()
for arg in "$@"; do
    if [[ "$arg" == "--json" ]]; then
        PRETTY=true
    else
        ARGS+=("$arg")
    fi
done

if [[ ${#ARGS[@]} -lt 2 ]]; then
    echo "Error: METHOD and PATH required. Usage: proxmox-api METHOD PATH [CURL_ARGS...]" >&2
    exit 1
fi

METHOD="${ARGS[0]}"
API_PATH="${ARGS[1]}"
EXTRA_ARGS=("${ARGS[@]:2}")

# ---------------------------------------------------------------------------
# Load environment
# ---------------------------------------------------------------------------

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

load_env() {
    # Already exported (user sourced envs/*/env)
    [[ -n "${PROXMOX_TOKEN_SECRET:-}" ]] && return

    # Check envs/*/env in repo root
    local repo_root
    repo_root=$(cd "$SCRIPT_DIR/../.." && pwd)
    for env_file in "${repo_root}"/envs/*/env; do
        if [[ -f "$env_file" ]]; then
            # shellcheck disable=SC1091
            source "$env_file"
            [[ -n "${PROXMOX_TOKEN_SECRET:-}" ]] && return
        fi
    done

    # Walk up from script dir (backward compat)
    local dir="$SCRIPT_DIR"
    while [[ "$dir" != "/" ]]; do
        if [[ -f "${dir}/env" ]]; then
            # shellcheck disable=SC1091
            source "${dir}/env"
            return
        fi
        dir="$(dirname "$dir")"
    done
}
load_env

if [[ -z "${PROXMOX_TOKEN_SECRET:-}" ]]; then
    echo "Error: PROXMOX_TOKEN_SECRET not set. Create an env file or export it." >&2
    exit 1
fi

# ---------------------------------------------------------------------------
# Load proxmox.yaml
# ---------------------------------------------------------------------------

yaml_get() {
    local file="$1" key="$2" default="${3:-}"
    local val
    val=$(awk -F': ' -v k="$key" '$1 == k {print $2; exit}' "$file" 2>/dev/null) || val=""
    val="${val#\"}" ; val="${val%\"}"
    val="${val#\'}" ; val="${val%\'}"
    echo "${val:-$default}"
}

find_proxmox_yaml() {
    local repo_root
    repo_root=$(cd "$SCRIPT_DIR/../.." && pwd)

    # Check envs/*/proxmox.yaml in repo root
    for f in "${repo_root}"/envs/*/proxmox.yaml; do
        if [[ -f "$f" ]]; then
            echo "$f"
            return
        fi
    done

    # Walk up from script dir (backward compat)
    local search_dirs=(
        "${SCRIPT_DIR}/.."
        "${repo_root}"
        "$(pwd)"
    )
    for dir in "${search_dirs[@]}"; do
        if [[ -f "${dir}/proxmox.yaml" ]]; then
            echo "${dir}/proxmox.yaml"
            return
        fi
    done
    echo ""
}

PROXMOX_YAML=$(find_proxmox_yaml)
if [[ -z "$PROXMOX_YAML" ]]; then
    echo "Error: proxmox.yaml not found" >&2
    exit 1
fi

PVE_HOST=$(yaml_get "$PROXMOX_YAML" "host")
PVE_TOKEN_ID=$(yaml_get "$PROXMOX_YAML" "api_token_id")

if [[ -z "$PVE_HOST" ]]; then
    echo "Error: proxmox.yaml: 'host' is required" >&2
    exit 1
fi
if [[ -z "$PVE_TOKEN_ID" ]]; then
    echo "Error: proxmox.yaml: 'api_token_id' is required" >&2
    exit 1
fi

# ---------------------------------------------------------------------------
# Make API call
# ---------------------------------------------------------------------------

# Build the full auth header in a variable (avoids ! expansion issues)
AUTH_HEADER="Authorization: PVEAPIToken=${PVE_TOKEN_ID}=${PROXMOX_TOKEN_SECRET}"

URL="https://${PVE_HOST}:8006/api2/json${API_PATH}"

CURL_CMD=(curl -fsSk -X "$METHOD" -H "$AUTH_HEADER")

if [[ ${#EXTRA_ARGS[@]} -gt 0 ]]; then
    CURL_CMD+=("${EXTRA_ARGS[@]}")
fi

CURL_CMD+=("$URL")

RESPONSE=$("${CURL_CMD[@]}" 2>&1) || {
    echo "Error: API call failed: $METHOD $API_PATH" >&2
    echo "$RESPONSE" >&2
    exit 1
}

if [[ "$PRETTY" == true ]]; then
    echo "$RESPONSE" | python3 -m json.tool 2>/dev/null || echo "$RESPONSE"
else
    echo "$RESPONSE"
fi
