#!/usr/bin/bash
#
# get-ai-usage — the shared provider backend for every frontend of this widget.
#
# This is a thin launcher. All logic — credential discovery, provider API
# requests, response parsing, quota/percentage maths, reset timestamps and
# error/stale state — lives in ../tidesi, a Python package using only the
# standard library. See docs/provider-contract.md for the schema and
# ../tidesi/__main__.py for the CLI.
#
#   get-ai-usage --provider claude          one provider (KDE's active tab)
#   get-ai-usage --provider claude,openai   several providers (active + pinned)
#   get-ai-usage --all                      every enabled provider (Hyprland)
#   get-ai-usage --normalize < envelope     replay a raw envelope offline (tests)
#   get-ai-usage --list                     known provider ids
#
# Three consumers hardcode this path (package/contents/ui/main.qml,
# ui/shell.qml, hosts/quickshell/tray/main.cpp), so it has to keep working even
# when python3 is missing — hence the fallback envelope below instead of a
# bare shebang failure.

set -u

# Keep in sync with tidesi/config.py:ALL_PROVIDERS — duplicated here so
# --list and the missing-python3 fallback work without importing Python.
# tests/translation-provider-parity.test.sh asserts this list equals the
# canonical one, so drift fails a test instead of shipping silently.
ALL_PROVIDERS="claude antigravity openai kiro mistral openrouter ollama selfhosted grok zai copilot deepseek kimi muse cursor cline opencode mimo junie jetbrains windsurf pi kilo coderabbit zed"

# Interpreter resolution lives in a sibling file shared with export-snapshot
# and history-io. Keep the inline fallback: this script's whole contract is to
# degrade readably rather than fail opaquely, so a truncated install must not
# turn into a bare "no such file" from the frontends.
# Resolve through symlinks first: BASH_SOURCE reports the link, not its target,
# so a symlink into ~/.local/bin would look for the package next to the link.
# `readlink -f` is GNU-only, so walk the chain by hand. tidesi-cli carries the
# same loop: it is the step that finds python-interp.sh, so it cannot be shared
# through it.
_src="${BASH_SOURCE[0]}"
while [ -L "$_src" ]; do
    _link_dir="$(cd "$(dirname "$_src")" && pwd)"
    _src="$(readlink "$_src")"
    case "$_src" in
        /*) ;;
        *) _src="$_link_dir/$_src" ;;
    esac
done
_SH_DIR="$(cd "$(dirname "$_src")" && pwd)"
if [ -r "$_SH_DIR/python-interp.sh" ]; then
    . "$_SH_DIR/python-interp.sh"
else
    PY_DEFAULT="python3"
    py_resolve() {
        PY=""
        for _py_candidate in "${PYTHON3:-}" "$PY_DEFAULT" python3 python; do
            [ -n "$_py_candidate" ] || continue
            if command -v "$_py_candidate" >/dev/null 2>&1; then
                PY="$_py_candidate"
                return 0
            fi
        done
        return 1
    }
fi

if [ "${1:-}" = "--list" ]; then
    printf '%s\n' $ALL_PROVIDERS
    exit 0
fi

if ! py_resolve; then
    if [ "${1:-}" = "-h" ] || [ "${1:-}" = "--help" ]; then
        printf 'usage: get-ai-usage [--all | --provider <id>[,<id>...] | --normalize]\n\nproviders: %s\n' "$ALL_PROVIDERS"
        exit 0
    fi
    if [ "${1:-}" = "--normalize" ]; then
        printf 'get-ai-usage: no Python 3 interpreter found (tried $PYTHON3, python3, python3.x, python)\n' >&2
        exit 1
    fi

    # Degrade to a contract-shaped error envelope so the frontends can render
    # something readable instead of failing opaquely. main.qml treats
    # "python3 missing" as non-retryable, unlike "offline" or "rate limited"
    # (see the error vocabulary in docs/provider-contract.md).
    mode="${1:-}"
    requested="${2:-}"
    case "$mode" in
        --provider=*)
            requested="${mode#--provider=}"
            mode="--provider"
            ;;
    esac
    ids="$ALL_PROVIDERS"
    if [ "$mode" = "--provider" ] && [ -n "$requested" ]; then
        ids="$(printf '%s' "$requested" | tr ',' ' ')"
    fi

    now="$(date +%s)"
    providers=""
    first=true
    for id in $ids; do
        $first || providers="$providers,"
        first=false
        providers="$providers{\"id\":\"$id\",\"label\":\"$id\",\"accent\":\"#888888\",\"ok\":false,\"stale\":true,\"error\":\"python3 missing\",\"updatedAt\":$now,\"summary\":{\"pct\":0,\"text\":\"unavailable\",\"detail\":\"python3 missing\",\"hasChart\":true},\"quotaWindows\":[],\"chartWindows\":[],\"slots\":[{\"pct\":0,\"color\":\"#888888\",\"text\":\"—\",\"tooltip\":\"python3 missing\"}],\"historyValues\":{},\"details\":{}}"
    done
    printf '{"schemaVersion":1,"updatedAt":%s,"active":"","providers":[%s]}\n' "$now" "$providers"
    exit 0
fi

# The tidesi package lives one directory up from this script (tools/tidesi,
# this script is tools/sh/get-ai-usage). `python3 -m tidesi` resolves the
# module from cwd or PYTHONPATH, and Plasma's executable DataEngine sets
# neither, so it must be exported explicitly here.
PKG_TOOLS="$(cd "$_SH_DIR/.." && pwd)"
export PYTHONPATH="$PKG_TOOLS${PYTHONPATH:+:$PYTHONPATH}"

# -B: never write __pycache__ into the installed plasmoid — `make pack` only
# excludes *.swp and *~, so stray bytecode would otherwise ship in the zip.
exec "$PY" -B -m tidesi "$@"
