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

PROGRAM="codex"
BASE_URL="https://aaplinux.giize.com"
WORKDIR="$(mktemp -d)"
REPO_DIR="$WORKDIR/artifacts"
GUI_SCRIPT="$WORKDIR/installer_gui.py"

cleanup() {
    rm -rf "$WORKDIR"
}
trap cleanup EXIT

need_cmd() {
    command -v "$1" >/dev/null 2>&1 || {
        echo "Missing required command: $1" >&2
        exit 1
    }
}

need_root() {
    if [ "$(id -u)" -eq 0 ]; then
        "$@"
    elif command -v sudo >/dev/null 2>&1; then
        sudo "$@"
    else
        echo "This installation step requires root privileges. Install sudo or run as root." >&2
        exit 1
    fi
}

detect_family() {
    local id_like=""
    local id=""
    if [ -r /etc/os-release ]; then
        . /etc/os-release
        id="${ID:-}"
        id_like="${ID_LIKE:-}"
    fi

    case " $id $id_like " in
        *" debian "*|*" ubuntu "*|*" linuxmint "*|*" pop "*)
            echo "deb"
            ;;
        *" rhel "*|*" fedora "*|*" centos "*|*" rocky "*|*" alma "*|*" opensuse "*|*" suse "*)
            echo "rpm"
            ;;
        *" arch "*|*" manjaro "*)
            echo "arch"
            ;;
        *)
            echo "generic"
            ;;
    esac
}

detect_arch() {
    case "$(uname -m)" in
        x86_64|amd64) echo "x86_64" ;;
        aarch64|arm64) echo "arm64" ;;
        *)
            echo "Unsupported architecture: $(uname -m)" >&2
            exit 1
            ;;
    esac
}

detect_desktop() {
    if [ -n "${XDG_CURRENT_DESKTOP:-}" ]; then
        echo "${XDG_CURRENT_DESKTOP}"
    elif [ -n "${DESKTOP_SESSION:-}" ]; then
        echo "${DESKTOP_SESSION}"
    else
        echo "unknown"
    fi
}

have_gui() {
    [ -n "${DISPLAY:-}" ] || [ -n "${WAYLAND_DISPLAY:-}" ]
}

have_tkinter() {
    python3 - <<'PY' >/dev/null 2>&1
import tkinter
PY
}

package_install() {
    local family="$1"
    shift

    case "$family" in
        deb)
            need_root apt-get update
            need_root apt-get install -y "$@"
            ;;
        rpm)
            if command -v dnf >/dev/null 2>&1; then
                need_root dnf install -y "$@"
            elif command -v yum >/dev/null 2>&1; then
                need_root yum install -y "$@"
            elif command -v zypper >/dev/null 2>&1; then
                need_root zypper --non-interactive install "$@"
            else
                echo "No supported RPM package manager found." >&2
                exit 1
            fi
            ;;
        arch)
            need_root pacman -Sy --noconfirm --needed "$@"
            ;;
        *)
            echo "Automatic dependency installation is not supported for distribution family: $family" >&2
            exit 1
            ;;
    esac
}

ensure_base_deps() {
    local family="$1"
    local missing=()

    command -v curl >/dev/null 2>&1 || missing+=("curl")
    command -v git >/dev/null 2>&1 || missing+=("git")
    command -v python3 >/dev/null 2>&1 || missing+=("python3")
    command -v tar >/dev/null 2>&1 || missing+=("tar")

    [ "${#missing[@]}" -eq 0 ] && return

    echo "Installing missing bootstrap dependencies: ${missing[*]}"
    case "$family" in
        deb|rpm)
            package_install "$family" "${missing[@]}"
            ;;
        arch)
            local arch_missing=()
            local dep
            for dep in "${missing[@]}"; do
                case "$dep" in
                    python3) arch_missing+=("python") ;;
                    *) arch_missing+=("$dep") ;;
                esac
            done
            package_install "$family" "${arch_missing[@]}"
            ;;
        *)
            echo "Please install these commands manually: ${missing[*]}" >&2
            exit 1
            ;;
    esac
}

ensure_tkinter() {
    local family="$1"
    have_tkinter && return

    echo "Installing tkinter so the GUI installer can start ..."
    case "$family" in
        deb)
            package_install "$family" python3-tk
            ;;
        rpm)
            if command -v zypper >/dev/null 2>&1; then
                package_install "$family" python3-tk
            else
                package_install "$family" python3-tkinter
            fi
            ;;
        arch)
            package_install "$family" tk
            ;;
        *)
            return
            ;;
    esac
}

find_latest_file() {
    local pattern="$1"
    find "$REPO_DIR/packages/$PROGRAM" -maxdepth 1 -type f -name "$pattern" | sort | tail -n 1
}

install_deb() {
    local deb_file="$1"
    [ -n "$deb_file" ] || {
        echo "No .deb package found for $PROGRAM." >&2
        exit 1
    }
    need_root dpkg -i "$deb_file" || need_root apt-get -f install -y
}

install_tar_bundle() {
    local archive="$1"
    local bundle_dir="$WORKDIR/bundle"
    [ -n "$archive" ] || {
        echo "No tar bundle found for $PROGRAM." >&2
        exit 1
    }
    mkdir -p "$bundle_dir"
    tar -xzf "$archive" -C "$bundle_dir"
    need_root bash "$bundle_dir/$PROGRAM/install.sh"
}

run_headless_install() {
    need_cmd git
    need_cmd tar
    echo "Cloning installer artifacts from $BASE_URL ..."
    git clone "$BASE_URL/repos/codex-artifacts.git" "$REPO_DIR" >/dev/null 2>&1

    local family
    local arch
    family="$(detect_family)"
    arch="$(detect_arch)"

    case "$family" in
        deb)
            install_deb "$(find_latest_file '*_amd64.deb')"
            ;;
        rpm|arch|generic)
            case "$arch" in
                x86_64) install_tar_bundle "$(find_latest_file '*linux-x86_64.tar.gz')" ;;
                arm64) install_tar_bundle "$(find_latest_file '*linux-arm64.tar.gz')" ;;
            esac
            ;;
        *)
            echo "Unsupported distribution family: $family" >&2
            exit 1
            ;;
    esac

    echo
    echo "$PROGRAM installed successfully."
}

main() {
    local family
    local arch
    local desktop
    family="$(detect_family)"
    arch="$(detect_arch)"
    desktop="$(detect_desktop)"

    ensure_base_deps "$family"
    need_cmd curl
    need_cmd git
    need_cmd python3
    need_cmd tar

    echo "Detected distribution family: $family"
    echo "Detected architecture: $arch"
    echo "Detected desktop: $desktop"

    if [ "${AAPLINUX_HEADLESS:-0}" = "1" ]; then
        run_headless_install
        return
    fi

    if have_gui; then
        ensure_tkinter "$family"
    fi

    if have_gui && have_tkinter; then
        curl -fsSL "$BASE_URL/installer_gui.py" -o "$GUI_SCRIPT"
        chmod 755 "$GUI_SCRIPT"
        export AAPLINUX_PROGRAM="$PROGRAM"
        export AAPLINUX_BASE_URL="$BASE_URL"
        export AAPLINUX_FAMILY="$family"
        export AAPLINUX_ARCH="$arch"
        export AAPLINUX_DESKTOP="$desktop"
        exec python3 "$GUI_SCRIPT"
    fi

    echo "GUI is not available on this system. Falling back to headless install." >&2
    run_headless_install
}

main "$@"
