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

API_URL="https://sonarify.ru/download/installers/?type=installers"
TMP_DIR="$(mktemp -d -t sonar-linux-install-XXXXXX)"
INSTALLER_PATH="$TMP_DIR/SonarInstaller"

log() {
    printf "[%s] %s\n" "$(date '+%Y-%m-%d %H:%M:%S')" "$1"
}

info() {
    log "[INFO] $1"
}

warn() {
    log "[WARN] $1"
}

error() {
    log "[ERROR] $1"
    exit 1
}

cleanup() {
    rm -rf "$TMP_DIR"
}

trap cleanup EXIT

command -v curl >/dev/null || error "Не найден curl"
command -v python3 >/dev/null || error "Не найден python3"

info "Запрашиваю список установщиков Sonar..."
INSTALLER_LIST_JSON="$(curl -fsSL --retry 3 --retry-delay 2 "$API_URL")"
if [[ -z "$INSTALLER_LIST_JSON" ]]; then
    error "Сервер установщиков вернул пустой ответ"
fi

pick_latest_file() {
    local ext="$1"
    local arch="$2"
    local selected=""
    selected="$(INSTALLER_LIST_JSON="$INSTALLER_LIST_JSON" python3 - "$ext" "$arch" <<'PY'
import json
import os
import re
import sys

ext = sys.argv[1].lower()
arch = (sys.argv[2] or "").lower()
payload = os.environ.get("INSTALLER_LIST_JSON", "")

try:
    data = json.loads(payload or "{}")
except Exception:
    raise SystemExit(2)

files = data.get("files")
if not isinstance(files, list):
    raise SystemExit(2)

files = [name for name in files if isinstance(name, str) and name.lower().endswith(ext)]
if arch:
    with_arch = [name for name in files if arch in name.lower()]
    if with_arch:
        files = with_arch

def version_key(name):
    match = re.search(r"(\\d+)\\.(\\d+)\\.(\\d+)", name)
    if match:
        return tuple(int(match.group(i)) for i in range(1, 4))
    return (0, 0, 0)

if not files:
    raise SystemExit(2)

files.sort(key=lambda name: (version_key(name), name.lower()))
print(files[-1], end="")
PY
)"

    if [[ -z "$selected" && -n "$arch" ]]; then
        selected="$(INSTALLER_LIST_JSON="$INSTALLER_LIST_JSON" python3 - "$ext" "" <<'PY'
import json
import os
import re
import sys

ext = sys.argv[1].lower()
payload = os.environ.get("INSTALLER_LIST_JSON", "")

try:
    data = json.loads(payload or "{}")
except Exception:
    raise SystemExit(2)

files = data.get("files")
if not isinstance(files, list):
    raise SystemExit(2)

files = [name for name in files if isinstance(name, str) and name.lower().endswith(ext)]

def version_key(name):
    match = re.search(r"(\\d+)\\.(\\d+)\\.(\\d+)", name)
    if match:
        return tuple(int(match.group(i)) for i in range(1, 4))
    return (0, 0, 0)

if not files:
    raise SystemExit(2)

files.sort(key=lambda name: (version_key(name), name.lower()))
print(files[-1], end="")
PY
)"
    fi

    if [[ -z "$selected" ]]; then
        return 1
    fi
    printf "%s" "$selected"
}

arch="$(uname -m)"
case "$arch" in
    arm64|aarch64) ARCH_FILTER="arm64" ;;
    x86_64|amd64) ARCH_FILTER="amd64" ;;
    i386|i686) ARCH_FILTER="386" ;;
    *) ARCH_FILTER="" ;;
esac

installer_file=""
for ext in ".AppImage" ".appimage" ".deb" ".rpm" ".pkg"; do
    candidate="$(pick_latest_file "$ext" "$ARCH_FILTER" || true)"
    if [[ -n "$candidate" ]]; then
        installer_file="$candidate"
        selected_ext="$ext"
        break
    fi
done

if [[ -z "$installer_file" ]]; then
    error "Не найден подходящий установщик (.AppImage/.deb/.rpm/.pkg)"
fi

INSTALLER_URL="${API_URL}&file=$(python3 - "$installer_file" <<'PY'
import urllib.parse
import sys
print(urllib.parse.quote(sys.argv[1]))
PY
)"

info "Скачиваю ${installer_file} ..."
curl --progress-bar -L --retry 3 --retry-delay 2 -o "$INSTALLER_PATH" "$INSTALLER_URL"
info "Загрузка завершена: $INSTALLER_PATH"

case "$selected_ext" in
    .AppImage|.appimage)
        info "Запускаю AppImage установщик..."
        chmod +x "$INSTALLER_PATH"
        "$INSTALLER_PATH"
        ;;
    .deb)
        if command -v dpkg >/dev/null && command -v apt-get >/dev/null; then
            if [[ ${EUID:-0} -eq 0 ]]; then
                info "Устанавливаю .deb пакет..."
                if ! dpkg -i "$INSTALLER_PATH"; then
                    warn "Выполняю исправление зависимостей через apt-get..."
                    apt-get -f install -y
                fi
            elif command -v sudo >/dev/null; then
                info "Устанавливаю .deb пакет через sudo..."
                if ! sudo dpkg -i "$INSTALLER_PATH"; then
                    warn "Выполняю исправление зависимостей через sudo apt-get..."
                    sudo apt-get -f install -y
                fi
            else
                error "Для установки .deb требуется root или sudo"
            fi
        else
            error "Система не поддерживает dpkg/apt-get для автоматической установки .deb"
        fi
        ;;
    .rpm)
        if command -v rpm >/dev/null; then
            if [[ ${EUID:-0} -eq 0 ]]; then
                info "Устанавливаю .rpm пакет..."
                rpm -Uvh "$INSTALLER_PATH"
            elif command -v sudo >/dev/null; then
                info "Устанавливаю .rpm пакет через sudo..."
                sudo rpm -Uvh "$INSTALLER_PATH"
            else
                error "Для установки .rpm требуется root или sudo"
            fi
        else
            error "Система не поддерживает rpm для автоматической установки .rpm"
        fi
        ;;
    .pkg)
        if [[ ${EUID:-0} -eq 0 ]]; then
            info "Устанавливаю .pkg пакет..."
            installer -pkg "$INSTALLER_PATH" -target /
        elif command -v sudo >/dev/null; then
            info "Устанавливаю .pkg пакет через sudo..."
            sudo installer -pkg "$INSTALLER_PATH" -target /
        else
            error "Для установки .pkg требуется root или sudo"
        fi
        ;;
    *)
        error "Неподдерживаемый формат установщика: $selected_ext"
        ;;
esac

info "Установка завершена"
