#!/usr/bin/env bash
#===============================================================================
# Loki Mode shim
#
# Routes commands ported in Phase 2 (bash->Bun migration) to the Bun CLI;
# everything else falls through to autonomy/loki (bash).
#
# Set LOKI_LEGACY_BASH=1 to force bash for every command (rollback flag).
# See docs/architecture/ADR-001-runtime-migration.md and
# /Users/lokesh/.claude/plans/polished-waddling-stardust.md.
#===============================================================================
set -euo pipefail

# Resolve script directory (handles symlinks like the bash CLI does).
_resolve_path() {
    local script="$1"
    if command -v realpath &>/dev/null; then
        realpath "$script" 2>/dev/null || echo "$script"
    else
        while [ -L "$script" ]; do
            local dir
            dir=$(dirname "$script")
            script=$(readlink "$script")
            [[ "$script" != /* ]] && script="$dir/$script"
        done
        echo "$script"
    fi
}

SCRIPT_PATH=$(_resolve_path "$0")
SCRIPT_DIR=$(dirname "$SCRIPT_PATH")
REPO_ROOT=$(cd "$SCRIPT_DIR/.." 2>/dev/null && pwd)
BASH_CLI="$REPO_ROOT/autonomy/loki"

# Resolve which Bun entry to use:
#   1. LOKI_TS_ENTRY=...   -- explicit override (custom builds, tests)
#   2. BUN_FROM_SOURCE=1   -- prefer src/cli.ts (used by bench --compare-dist
#                             and during Phase 3 development before dist ships)
#   3. dist/loki.js exists -- production path (npm/Docker/Homebrew artifact)
#   4. fall back to src    -- in-repo development before first build
#
# v7.4.2 fix (BUG-1): BUN_FROM_SOURCE=1 used to hard-fail on npm/Docker/brew
# installs because src/ is excluded by .npmignore. Now we warn once and fall
# back to dist if src/cli.ts is missing.
if [ -n "${LOKI_TS_ENTRY:-}" ]; then
    # v7.5.1 fix B18: validate that the explicit override actually exists.
    # Pre-v7.5.1 a typo (LOKI_TS_ENTRY=/nonexistent) produced a raw Bun
    # "Module not found" error with no hint about the env var. Now we warn
    # to stderr and fall through to the bash CLI so the user can still
    # invoke commands while they fix the path.
    if [ ! -f "$LOKI_TS_ENTRY" ]; then
        echo "ERROR: LOKI_TS_ENTRY=$LOKI_TS_ENTRY does not exist; falling through to bash CLI. Unset the variable or fix the path." >&2
        exec "$BASH_CLI" "$@"
    fi
    BUN_CLI="$LOKI_TS_ENTRY"
elif [ "${BUN_FROM_SOURCE:-0}" = "1" ] || [ "${BUN_FROM_SOURCE:-}" = "true" ]; then
    if [ -f "$REPO_ROOT/loki-ts/src/cli.ts" ]; then
        BUN_CLI="$REPO_ROOT/loki-ts/src/cli.ts"
    elif [ -f "$REPO_ROOT/loki-ts/dist/loki.js" ]; then
        echo "WARN: BUN_FROM_SOURCE set but loki-ts/src/cli.ts missing (typical for npm/Docker/brew installs); using dist/loki.js" >&2
        BUN_CLI="$REPO_ROOT/loki-ts/dist/loki.js"
    else
        echo "ERROR: BUN_FROM_SOURCE set but neither src/cli.ts nor dist/loki.js found; falling through to bash" >&2
        exec "$BASH_CLI" "$@"
    fi
elif [ -f "$REPO_ROOT/loki-ts/dist/loki.js" ]; then
    BUN_CLI="$REPO_ROOT/loki-ts/dist/loki.js"
elif [ -f "$REPO_ROOT/loki-ts/src/cli.ts" ]; then
    BUN_CLI="$REPO_ROOT/loki-ts/src/cli.ts"
else
    # Neither dist nor src available; fall through to bash silently.
    exec "$BASH_CLI" "$@"
fi

# v7.4.13: one-shot first-run telemetry, MOVED from autonomy/loki main()
# into the shim because the 8 ported commands (version, status, doctor,
# stats, provider, memory) bypass main() entirely -- only unported
# commands triggered the original hook. Now fires regardless of route.
# Fire-and-forget; opt-out via LOKI_TELEMETRY_DISABLED=true or
# DO_NOT_TRACK=1 (mirrors autonomy/telemetry.sh contract).
if [ -z "${LOKI_TELEMETRY_DISABLED:-}" ] && [ "${DO_NOT_TRACK:-}" != "1" ] && [ ! -f "${HOME}/.loki-first-run" ] 2>/dev/null; then
    touch "${HOME}/.loki-first-run" 2>/dev/null || true
    if command -v curl &>/dev/null && [ -f "$REPO_ROOT/autonomy/telemetry.sh" ]; then
        # Source telemetry helpers + fire installed event in background
        # so the user does not pay latency on first invocation.
        # Detach all three FDs so the backgrounded subshell never holds this
        # shim's stdout/stderr/stdin open (v7.8.3: same fix as the cli_command
        # emit below -- prevents a macOS broken-pipe in piped callers).
        ( SCRIPT_DIR="$REPO_ROOT/autonomy"; source "$SCRIPT_DIR/telemetry.sh" 2>/dev/null && loki_telemetry "installed" "first_command=${1:-}" 2>/dev/null ) >/dev/null 2>&1 </dev/null &
        disown 2>/dev/null || true
    fi
fi

# v7.5.18: Guard against deprecated LOKI_PROVIDER=gemini before routing.
# Fires for all commands (Bun-routed and bash-routed) so users get a clear
# error regardless of which subcommand they invoke.
if [ "${LOKI_PROVIDER:-}" = "gemini" ]; then
    echo "Error: Provider 'gemini' is deprecated as of v7.5.18 and has been removed." >&2
    echo "Active providers: claude, codex, cline, aider" >&2
    echo "Unset LOKI_PROVIDER or use: LOKI_PROVIDER=claude" >&2
    exit 1
fi

# Force-fall-through to bash when the rollback flag is set.
if [ "${LOKI_LEGACY_BASH:-0}" = "1" ] || [ "${LOKI_LEGACY_BASH:-}" = "true" ]; then
    exec "$BASH_CLI" "$@"
fi

# Bun must be installed for the new path; if it isn't, fall through to bash
# silently rather than fail. This keeps users on systems without Bun working.
if ! command -v bun &>/dev/null; then
    exec "$BASH_CLI" "$@"
fi

# Commands ported in Phase 2 -- route to Bun. Everything else goes to bash.
# Two-token routes (provider show/list, memory list/index) match on the first
# token only; the Bun dispatcher handles subcommand routing internally.
case "${1:-}" in
    version|--version|-v|status|stats|doctor|provider|memory|rollback|internal|kpis|trust|proof|wiki|crash)
        # v7.5.2: rollback added (wires loki-ts/src/commands/rollback.ts).
        # v7.5.3: internal added for autonomy/run.sh phase1-hooks calls.
        # v7.5.28: kpis added (Phase K MVP: read-only KPI snapshot).
        # R4: trust added (visible trust trajectory; Bun route, bash fallback).
        # crash added (Crash Reporting Phase 0: inspect/manually submit local
        # scrubbed crash reports; Bun route, bash fallback).
        #
        # v7.8.2: emit the cli_command product-analytics event for Bun-routed
        # commands. The bash CLI fires this from autonomy/loki main(), but the
        # ported commands above bypass main() entirely, so Bun-routed
        # invocations were invisible to usage analytics. Fire it here, before
        # the exec, so it covers every Bun command exactly once (no
        # double-count: the bash route still emits its own copy in main()).
        # Fire-and-forget, backgrounded, opt-out honored by loki_telemetry
        # itself (LOKI_TELEMETRY_DISABLED / DO_NOT_TRACK). The command token is
        # the subcommand name only -- never args, flags, or paths.
        if command -v curl &>/dev/null && [ -f "$REPO_ROOT/autonomy/telemetry.sh" ]; then
            # Detach all three FDs (</dev/null >/dev/null 2>&1) so the
            # backgrounded subshell does not inherit and hold this shim's
            # stdout/stderr/stdin open. Without this, the lingering FD changed
            # pipe-teardown timing and produced a macOS-only broken-pipe in the
            # shim-route CLI test harness (v7.8.2 -> fixed v7.8.3).
            ( SCRIPT_DIR="$REPO_ROOT/autonomy"; source "$SCRIPT_DIR/telemetry.sh" 2>/dev/null && loki_telemetry "cli_command" "command=${1:-}" 2>/dev/null ) >/dev/null 2>&1 </dev/null &
            disown 2>/dev/null || true
        fi
        exec bun "$BUN_CLI" "$@"
        ;;
    *)
        exec "$BASH_CLI" "$@"
        ;;
esac
