#!/usr/bin/env bash
# run-resources.sh — Infrastructure resource snapshot.
#
# Collects disk usage, RAM usage, Anthropic API call counts and budget burn,
# and Woodpecker CI queue depth.  Writes evidence/resources/YYYY-MM-DD.json.
#
# Exit codes:
#   0  snapshot written successfully
#   2  infrastructure error
#
# Environment:
#   DISK_PATH                      filesystem to measure (default: /)
#   ANTHROPIC_BUDGET_USD_LIMIT     budget ceiling in USD (default: 50)
#   WOODPECKER_API_URL             Woodpecker CI base URL (default: http://localhost:8090; empty to skip)

set -euo pipefail

REPO_ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
DATE="$(date -u +%Y-%m-%d)"
OUT_DIR="$REPO_ROOT/evidence/resources"
OUT_FILE="$OUT_DIR/$DATE.json"
CALL_LOG="$REPO_ROOT/tmp/anthropic-call-log.jsonl"

DISK_PATH="${DISK_PATH:-/}"
ANTHROPIC_BUDGET_USD_LIMIT="${ANTHROPIC_BUDGET_USD_LIMIT:-50}"
WOODPECKER_API_URL="${WOODPECKER_API_URL:-http://localhost:8090}"

die() { echo "ERROR: $*" >&2; exit 2; }

mkdir -p "$OUT_DIR"

# ── collect-disk ──────────────────────────────────────────────────────────────

disk_used_bytes=0
disk_total_bytes=0
disk_used_pct=0

if command -v df >/dev/null 2>&1; then
    # -B1 gives bytes; tail -1 skips header; awk grabs used, total, pct
    read -r disk_total_bytes disk_used_bytes disk_used_pct < <(
        df -B1 "$DISK_PATH" | tail -1 | awk '{gsub(/%/,"",$5); print $2, $3, $5}'
    )
else
    echo "WARN: df not available, disk metrics will be 0" >&2
fi

# ── collect-ram ───────────────────────────────────────────────────────────────

ram_used_bytes=0
ram_total_bytes=0
ram_used_pct=0

if command -v free >/dev/null 2>&1; then
    # free -b: second line (Mem:) has total, used
    read -r ram_total_bytes ram_used_bytes < <(
        free -b | awk '/^Mem:/ {print $2, $3}'
    )
    if [[ "$ram_total_bytes" -gt 0 ]]; then
        ram_used_pct=$(awk "BEGIN {printf \"%.1f\", $ram_used_bytes / $ram_total_bytes * 100}")
    fi
elif command -v vm_stat >/dev/null 2>&1; then
    # macOS fallback
    page_size=$(vm_stat | head -1 | grep -o '[0-9]*')
    pages_active=$(vm_stat | awk '/Pages active/ {gsub(/\./,"",$3); print $3}')
    pages_wired=$(vm_stat | awk '/Pages wired/ {gsub(/\./,"",$4); print $4}')
    pages_free=$(vm_stat | awk '/Pages free/ {gsub(/\./,"",$3); print $3}')
    pages_inactive=$(vm_stat | awk '/Pages inactive/ {gsub(/\./,"",$3); print $3}')
    ram_used_bytes=$(( (pages_active + pages_wired) * page_size ))
    ram_total_bytes=$(( (pages_active + pages_wired + pages_free + pages_inactive) * page_size ))
    if [[ "$ram_total_bytes" -gt 0 ]]; then
        ram_used_pct=$(awk "BEGIN {printf \"%.1f\", $ram_used_bytes / $ram_total_bytes * 100}")
    fi
else
    echo "WARN: neither free nor vm_stat available, RAM metrics will be 0" >&2
fi

# ── collect-api ───────────────────────────────────────────────────────────────

anthropic_calls_24h=0
anthropic_budget_usd_used=0
anthropic_budget_pct=0

if [[ -f "$CALL_LOG" ]]; then
    cutoff=$(date -u -d '24 hours ago' +%Y-%m-%dT%H:%M:%S 2>/dev/null \
          || date -u -v-24H +%Y-%m-%dT%H:%M:%S 2>/dev/null \
          || echo "")
    today=$(date -u +%Y-%m-%d)

    if [[ -n "$cutoff" ]]; then
        anthropic_calls_24h=$(awk -F'"ts"' -v cutoff="$cutoff" '
            NF>1 { split($2,a,"\""); if (a[2] >= cutoff) count++ }
            END { print count+0 }
        ' "$CALL_LOG")
    fi

    anthropic_budget_usd_used=$(awk -F'"' -v today="$today" '
        /"ts"/ && $0 ~ today {
            match($0, /"cost_usd"[[:space:]]*:[[:space:]]*([0-9.]+)/, m)
            if (m[1] != "") sum += m[1]
        }
        END { printf "%.2f", sum+0 }
    ' "$CALL_LOG")
fi

if [[ "$ANTHROPIC_BUDGET_USD_LIMIT" != "0" ]]; then
    anthropic_budget_pct=$(awk "BEGIN {printf \"%.1f\", $anthropic_budget_usd_used / $ANTHROPIC_BUDGET_USD_LIMIT * 100}")
fi

# ── collect-ci ────────────────────────────────────────────────────────────────

woodpecker_queue_depth="null"
woodpecker_running="null"

if [[ -n "$WOODPECKER_API_URL" ]]; then
    if ci_json=$(curl -sf --max-time 5 "$WOODPECKER_API_URL/api/queue/info" 2>/dev/null); then
        woodpecker_queue_depth=$(echo "$ci_json" | jq '.pending // .waiting // 0')
        woodpecker_running=$(echo "$ci_json" | jq '.running // 0')
    else
        echo "WARN: Woodpecker CI unreachable at $WOODPECKER_API_URL, CI metrics will be null" >&2
    fi
fi

# ── verdict ───────────────────────────────────────────────────────────────────

verdict="ok"

for pct in "$disk_used_pct" "$ram_used_pct" "$anthropic_budget_pct"; do
    # Strip trailing % if present
    pct_num="${pct//%/}"
    if awk "BEGIN {exit !($pct_num >= 95)}"; then
        verdict="critical"
        break
    fi
    if awk "BEGIN {exit !($pct_num >= 80)}"; then
        verdict="warn"
    fi
done

# ── write JSON ────────────────────────────────────────────────────────────────

cat > "$OUT_FILE" <<ENDJSON
{
  "date": "$DATE",
  "disk": {
    "used_bytes": $disk_used_bytes,
    "total_bytes": $disk_total_bytes,
    "used_pct": $disk_used_pct
  },
  "ram": {
    "used_bytes": $ram_used_bytes,
    "total_bytes": $ram_total_bytes,
    "used_pct": $ram_used_pct
  },
  "api": {
    "anthropic_calls_24h": $anthropic_calls_24h,
    "anthropic_budget_usd_used": $anthropic_budget_usd_used,
    "anthropic_budget_usd_limit": $ANTHROPIC_BUDGET_USD_LIMIT,
    "anthropic_budget_pct": $anthropic_budget_pct
  },
  "ci": {
    "woodpecker_queue_depth": $woodpecker_queue_depth,
    "woodpecker_running": $woodpecker_running
  },
  "staleness_threshold_days": 1,
  "verdict": "$verdict"
}
ENDJSON

echo "evidence/resources/$DATE.json written — verdict: $verdict"
