#!/usr/bin/env bash
# Ilum CLI Installer
# Usage: curl -fsSL https://get.ilum.cloud/cli | bash
#   or:  ILUM_VERSION=0.2.0 bash install.sh
set -euo pipefail

REPO="ilum-cloud/ilum-cli"
INSTALL_DIR="${ILUM_INSTALL_DIR:-/usr/local/bin}"
FALLBACK_DIR="${ILUM_FALLBACK_DIR:-${HOME}/.local/bin}"

# Colours (when stdout is a terminal)
if [ -t 1 ]; then
    RED='\033[0;31m'
    GREEN='\033[0;32m'
    YELLOW='\033[0;33m'
    BLUE='\033[0;34m'
    NC='\033[0m'
else
    RED='' GREEN='' YELLOW='' BLUE='' NC=''
fi

info()  { printf "${BLUE}==>${NC} %s\n" "$*"; }
ok()    { printf "${GREEN}==>${NC} %s\n" "$*"; }
warn()  { printf "${YELLOW}WARNING:${NC} %s\n" "$*"; }
err()   { printf "${RED}ERROR:${NC} %s\n" "$*" >&2; }
die()   { err "$@"; exit 1; }

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

NO_PATH_SETUP=0
CLI_VERSION=""

while [ $# -gt 0 ]; do
    case "$1" in
        --version)
            CLI_VERSION="$2"
            shift 2
            ;;
        --no-path)
            NO_PATH_SETUP=1
            shift
            ;;
        -h|--help)
            echo "Usage: install.sh [OPTIONS]"
            echo ""
            echo "Options:"
            echo "  --version <ver>  Install a specific version (e.g. 0.2.0)"
            echo "  --no-path        Skip PATH setup"
            echo "  -h, --help       Show this help"
            exit 0
            ;;
        *)
            err "Unknown argument: $1"
            exit 1
            ;;
    esac
done

# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------

fetch() {
    if command -v curl >/dev/null 2>&1; then
        curl -fsSL "$@"
    elif command -v wget >/dev/null 2>&1; then
        wget -qO- "$@"
    else
        die "Neither curl nor wget found. Please install one of them."
    fi
}

detect_platform() {
    OS=$(uname -s | tr '[:upper:]' '[:lower:]')
    ARCH=$(uname -m)
    case "$ARCH" in
        x86_64)         ARCH="amd64" ;;
        aarch64|arm64)  ARCH="arm64" ;;
        *)              die "Unsupported architecture: $ARCH" ;;
    esac

    case "$OS" in
        linux|darwin) ;;
        *)            die "Unsupported operating system: $OS" ;;
    esac

    PLATFORM="${OS}-${ARCH}"
    info "Detected platform: ${PLATFORM}"
}

determine_version() {
    if [ -n "$CLI_VERSION" ]; then
        info "Using version from --version flag: $CLI_VERSION"
        VERSION="$CLI_VERSION"
        return
    fi

    if [ -n "${ILUM_VERSION:-}" ]; then
        VERSION="${ILUM_VERSION}"
        info "Using pinned version: ${VERSION}"
        return
    fi

    info "Querying latest release from GitHub..."
    VERSION=$(fetch "${ILUM_GITHUB_API:-https://api.github.com}/repos/${REPO}/releases/latest" \
        | grep '"tag_name"' \
        | sed -E 's/.*"tag_name": *"cli-v([^"]+)".*/\1/')

    if [ -z "${VERSION:-}" ]; then
        die "Could not determine latest version. Set ILUM_VERSION manually."
    fi
    info "Latest version: ${VERSION}"
}

# ---------------------------------------------------------------------------
# Installation strategies (tiered fallback)
# ---------------------------------------------------------------------------

try_brew_install() {
    [ "$(uname -s)" = "Darwin" ] || return 1
    command -v brew >/dev/null 2>&1 || return 1
    info "Installing via Homebrew..."
    brew tap ilum-cloud/tap https://github.com/ilum-cloud/ilum 2>/dev/null
    brew install ilum && return 0
    warn "Homebrew install failed, trying next method..."
    return 1
}

try_pipx_install() {
    command -v pipx >/dev/null 2>&1 || return 1
    info "Installing via pipx..."
    pipx install "ilum==${VERSION}" && return 0
    warn "pipx install failed, trying next method..."
    return 1
}

try_uv_install() {
    command -v uv >/dev/null 2>&1 || return 1
    info "Installing via uv..."
    uv tool install "ilum==${VERSION}" && return 0
    warn "uv install failed, trying next method..."
    return 1
}

download_binary() {
    local tarball="ilum-${PLATFORM}.tar.gz"
    local base_url="${ILUM_DOWNLOAD_BASE:-https://github.com}/${REPO}/releases/download/cli-v${VERSION}"
    local tmpdir
    tmpdir=$(mktemp -d)
    trap "rm -rf '${tmpdir}'" EXIT

    info "Downloading ${tarball}..."
    fetch "${base_url}/${tarball}" > "${tmpdir}/${tarball}"
    fetch "${base_url}/SHA256SUMS"  > "${tmpdir}/SHA256SUMS"

    # Verify checksum
    info "Verifying checksum..."
    (cd "${tmpdir}" && grep "${tarball}" SHA256SUMS | sha256sum -c --quiet 2>/dev/null) || \
    (cd "${tmpdir}" && grep "${tarball}" SHA256SUMS | shasum -a 256 -c --quiet 2>/dev/null) || \
        die "Checksum verification failed!"
    ok "Checksum OK"

    # Extract
    tar -xzf "${tmpdir}/${tarball}" -C "${tmpdir}"

    # Install binary
    local target="${INSTALL_DIR}/ilum"
    if [ -w "${INSTALL_DIR}" ]; then
        mv "${tmpdir}/ilum" "${target}"
        chmod +x "${target}"
    elif command -v sudo >/dev/null 2>&1; then
        info "Installing to ${INSTALL_DIR} (requires sudo)..."
        sudo mv "${tmpdir}/ilum" "${target}"
        sudo chmod +x "${target}"
    else
        # Fallback to user directory
        mkdir -p "${FALLBACK_DIR}"
        target="${FALLBACK_DIR}/ilum"
        mv "${tmpdir}/ilum" "${target}"
        chmod +x "${target}"
        warn "${FALLBACK_DIR} may not be in your PATH."
        warn "Add it with: export PATH=\"${FALLBACK_DIR}:\$PATH\""
    fi

    ok "Installed ilum to ${target}"
}

# ---------------------------------------------------------------------------
# PATH setup
# ---------------------------------------------------------------------------

setup_path() {
    local install_dir="$1"

    if [ "$NO_PATH_SETUP" -eq 1 ]; then
        return
    fi

    # Check if already in PATH
    case ":$PATH:" in
        *":$install_dir:"*) return ;;
    esac

    local shell_name
    shell_name="$(basename "${SHELL:-/bin/bash}")"
    local rc_file=""

    case "$shell_name" in
        bash) rc_file="$HOME/.bashrc" ;;
        zsh)  rc_file="$HOME/.zshrc" ;;
        fish) rc_file="$HOME/.config/fish/config.fish" ;;
        *)    rc_file="" ;;
    esac

    if [ -z "$rc_file" ]; then
        warn "$install_dir is not in your PATH."
        info "Add it manually: export PATH=\"$install_dir:\$PATH\""
        return
    fi

    local path_line="export PATH=\"$install_dir:\$PATH\""
    if [ "$shell_name" = "fish" ]; then
        path_line="set -gx PATH $install_dir \$PATH"
    fi

    # Idempotency check
    if [ -f "$rc_file" ] && grep -qF "$install_dir" "$rc_file" 2>/dev/null; then
        info "$install_dir already in $rc_file"
        return
    fi

    info "Adding $install_dir to PATH in $rc_file"
    mkdir -p "$(dirname "$rc_file")"
    echo "" >> "$rc_file"
    echo "# Added by ilum CLI installer" >> "$rc_file"
    echo "$path_line" >> "$rc_file"
    ok "Updated $rc_file — restart your shell or run: source $rc_file"
}

# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------

main() {
    info "Ilum CLI Installer"
    echo

    detect_platform
    determine_version
    echo

    # Tiered fallback: brew (macOS) → pipx → uv → binary download
    if try_brew_install; then
        ok "Ilum CLI installed via Homebrew"
        return 0
    fi

    if try_pipx_install; then
        ok "Ilum CLI ${VERSION} installed via pipx"
        return 0
    fi

    if try_uv_install; then
        ok "Ilum CLI ${VERSION} installed via uv"
        return 0
    fi

    info "Falling back to binary download..."
    download_binary

    echo
    ok "Ilum CLI ${VERSION} installed successfully!"
    info "Run 'ilum init' to get started."

    # PATH setup
    setup_path "${INSTALL_DIR}"

    # Verify installation
    if command -v ilum >/dev/null 2>&1; then
        local installed_version
        installed_version="$(ilum --version 2>&1 || true)"
        if echo "$installed_version" | grep -q "$VERSION"; then
            ok "Verified: $installed_version"
        else
            warn "Version mismatch: expected $VERSION, got: $installed_version"
        fi
    else
        local shell_name rc_hint
        shell_name="$(basename "${SHELL:-/bin/bash}")"
        case "$shell_name" in
            bash) rc_hint="$HOME/.bashrc" ;;
            zsh)  rc_hint="$HOME/.zshrc" ;;
            fish) rc_hint="$HOME/.config/fish/config.fish" ;;
            *)    rc_hint="your shell rc file" ;;
        esac
        info "Run 'source $rc_hint' or restart your terminal, then run: ilum --version"
    fi
}

main "$@"
