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

# openmux npm/bun bin wrapper
# Downloads binary to XDG-compliant directories on first run if missing

REPO="monotykamary/openmux"

# XDG Base Directory compliance
# https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}"
BIN_DIR="${XDG_DATA_HOME}/openmux"

# Find package.json to get version
find_package_json() {
    local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

    # Check if we're in the package's bin directory
    if [[ -f "$(dirname "$script_dir")/package.json" ]]; then
        echo "$(dirname "$script_dir")/package.json"
        return
    fi

    # Bun global
    if [[ -f "$HOME/.bun/install/global/node_modules/openmux/package.json" ]]; then
        echo "$HOME/.bun/install/global/node_modules/openmux/package.json"
        return
    fi

    # npm global
    local npm_prefix
    npm_prefix="$(npm prefix -g 2>/dev/null || echo "")"
    if [[ -n "$npm_prefix" && -f "$npm_prefix/lib/node_modules/openmux/package.json" ]]; then
        echo "$npm_prefix/lib/node_modules/openmux/package.json"
        return
    fi

    # Fallback locations
    local locations=(
        "/usr/local/lib/node_modules/openmux/package.json"
        "/usr/lib/node_modules/openmux/package.json"
        "$HOME/.npm-global/lib/node_modules/openmux/package.json"
    )
    for loc in "${locations[@]}"; do
        if [[ -f "$loc" ]]; then
            echo "$loc"
            return
        fi
    done

    echo ""
}

get_version() {
    local pkg_json="$1"
    if [[ -f "$pkg_json" ]]; then
        grep '"version"' "$pkg_json" | head -1 | sed 's/.*"version": *"\([^"]*\)".*/\1/'
    else
        echo ""
    fi
}

get_platform() {
    local os arch
    os="$(uname -s)"
    arch="$(uname -m)"

    case "$os" in
        Darwin) os="darwin" ;;
        Linux) os="linux" ;;
        *) echo ""; return ;;
    esac

    case "$arch" in
        x86_64|amd64) arch="x64" ;;
        arm64|aarch64) arch="arm64" ;;
        *) echo ""; return ;;
    esac

    echo "${os}-${arch}"
}

spinner() {
    local pid=$1
    local spin='⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏'
    local i=0
    while kill -0 "$pid" 2>/dev/null; do
        printf "\r  %s %s" "${spin:i++%${#spin}:1}" "$2"
        sleep 0.1
    done
    printf "\r\033[K"
}

download_binary() {
    local version="$1"
    local platform="$(get_platform)"

    if [[ -z "$platform" ]]; then
        echo "Error: Unsupported platform" >&2
        return 1
    fi

    local url="https://github.com/$REPO/releases/download/v$version/openmux-v$version-$platform.tar.gz"

    printf "\n"
    printf "  \033[1mopenmux\033[0m v%s\n" "$version"
    printf "  Setting up for first run...\n"
    printf "\n"

    mkdir -p "$BIN_DIR"
    local tmp_file="$BIN_DIR/download.tar.gz"

    # Download with spinner
    if command -v curl &>/dev/null; then
        curl -fsSL "$url" -o "$tmp_file" 2>/dev/null &
    elif command -v wget &>/dev/null; then
        wget -q "$url" -O "$tmp_file" 2>/dev/null &
    else
        echo "Error: curl or wget required" >&2
        return 1
    fi
    spinner $! "Downloading..."
    wait $! || { printf "  \033[31mDownload failed\033[0m\n"; return 1; }
    printf "  \033[32m✓\033[0m Downloaded\n"

    # Extract with spinner
    tar -xzf "$tmp_file" -C "$BIN_DIR" &
    spinner $! "Extracting..."
    wait $!
    rm -f "$tmp_file"
    printf "  \033[32m✓\033[0m Extracted\n"

    # Make executable
    chmod +x "$BIN_DIR/openmux-bin" 2>/dev/null || true

    # Create empty bunfig.toml to prevent reading user's project config
    echo "# openmux runtime config (empty - preload already compiled in)" > "$BIN_DIR/bunfig.toml"

    # Write version file for upgrade detection
    echo "$version" > "$BIN_DIR/.version"

    printf "\n"
    printf "  \033[32mReady!\033[0m Starting openmux...\n"
    printf "\n"
}

# Determine library extension based on OS
case "$(uname -s)" in
    Darwin) LIB_EXT="dylib" ;;
    Linux) LIB_EXT="so" ;;
    *) echo "Unsupported OS" >&2; exit 1 ;;
esac

# Capture original cwd before any cd operations (for initial shell directory)
export OPENMUX_ORIGINAL_CWD="${OPENMUX_ORIGINAL_CWD:-$(pwd)}"

# Get package version
PKG_JSON="$(find_package_json)"
if [[ -z "$PKG_JSON" ]]; then
    # Fallback: if binary exists, just run it
    if [[ -x "$BIN_DIR/openmux-bin" ]]; then
        # Ensure empty bunfig.toml exists
        if [[ ! -f "$BIN_DIR/bunfig.toml" ]]; then
            echo "# openmux runtime config (empty - preload already compiled in)" > "$BIN_DIR/bunfig.toml"
        fi
        if [[ -f "$BIN_DIR/.version" ]]; then
            export OPENMUX_VERSION="$(cat "$BIN_DIR/.version")"
        fi
        export ZIG_PTY_LIB="${ZIG_PTY_LIB:-$BIN_DIR/libzig_pty.$LIB_EXT}"
        # cd to BIN_DIR to avoid reading user's bunfig.toml
        cd "$BIN_DIR"
        exec "./openmux-bin" "$@"
    fi
    echo "Error: Could not find openmux package" >&2
    exit 1
fi

VERSION="$(get_version "$PKG_JSON")"
if [[ -z "$VERSION" ]]; then
    echo "Error: Could not determine openmux version" >&2
    exit 1
fi

# Check if binary exists and matches version
INSTALLED_VERSION=""
if [[ -f "$BIN_DIR/.version" ]]; then
    INSTALLED_VERSION="$(cat "$BIN_DIR/.version")"
fi

if [[ ! -x "$BIN_DIR/openmux-bin" ]] || [[ "$INSTALLED_VERSION" != "$VERSION" ]]; then
    download_binary "$VERSION" || exit 1
fi

# Ensure empty bunfig.toml exists (for older releases that didn't include it)
if [[ ! -f "$BIN_DIR/bunfig.toml" ]]; then
    echo "# openmux runtime config (empty - preload already compiled in)" > "$BIN_DIR/bunfig.toml"
fi

# Set library path, cd to BIN_DIR to avoid user's bunfig.toml, and execute
export ZIG_PTY_LIB="${ZIG_PTY_LIB:-$BIN_DIR/libzig_pty.$LIB_EXT}"
export OPENMUX_VERSION="$VERSION"
cd "$BIN_DIR"
exec "./openmux-bin" "$@"
