#!/usr/bin/env bash
#
# Rosistem Remote Support - Installer Linux preconfigurat cu auto-enrollment
#
# Utilizare: descarca fisierul si ruleaza:
#   chmod +x Rosistem-Remote-Support-Setup.sh
#   sudo ./Rosistem-Remote-Support-Setup.sh
#
# Detecteaza distro (Debian/Ubuntu/Fedora/RHEL/Suse/openSUSE/Arch),
# descarca RustDesk corespunzator de pe GitHub, instaleaza silent,
# configureaza serverul Rosistem + cheia + parola unica, porneste
# serviciul si trimite enrollment-ul.
#
set -euo pipefail

# === Configuratie Rosistem (NU MODIFICA fara update pe server) ==============
SERVER_HOST="remote.rosistem.app"
SERVER_KEY="PdBomwgR3X7wxz7VY4JfhbeIzBo63qDHmDvE3KwdIgo="
API_URL="https://remote.rosistem.app"
ENROLL_URL="https://remote.rosistem.app/enroll"
ENROLL_SECRET="cHZgRRdVsuID1SCHbMbDpOKwqeFLZHFTEwPMaVM8g80"
RUSTDESK_VERSION="1.4.7"

# === Output helpers ==========================================================
C_CYAN="\033[0;36m"; C_GREEN="\033[0;32m"; C_RED="\033[0;31m"; C_YELL="\033[0;33m"; C_NC="\033[0m"
step() { echo -e "${C_CYAN}[*]${C_NC} $*"; }
ok()   { echo -e "${C_GREEN}[OK]${C_NC} $*"; }
err()  { echo -e "${C_RED}[X]${C_NC} $*" >&2; }
warn() { echo -e "${C_YELL}[!]${C_NC} $*"; }

# === Verificari ==============================================================
echo ""
echo "==================================================="
echo " Rosistem Remote Support - Instalare RustDesk"
echo "==================================================="

if [[ $EUID -ne 0 ]]; then
    err "Acest script trebuie rulat ca root. Foloseste: sudo $0"
    exit 1
fi

if ! command -v curl >/dev/null 2>&1; then
    step "Instalez curl..."
    if command -v apt-get >/dev/null 2>&1; then apt-get install -y curl
    elif command -v dnf >/dev/null 2>&1; then dnf install -y curl
    elif command -v yum >/dev/null 2>&1; then yum install -y curl
    elif command -v zypper >/dev/null 2>&1; then zypper install -y curl
    elif command -v pacman >/dev/null 2>&1; then pacman -S --noconfirm curl
    else err "curl lipseste si nu stiu cum sa-l instalez. Instaleaza-l manual."; exit 1
    fi
fi

# === Detectie distro + arhitectura ==========================================
ARCH=$(uname -m)
case "$ARCH" in
    x86_64|amd64) PKG_ARCH="x86_64" ;;
    aarch64|arm64) PKG_ARCH="aarch64" ;;
    armv7l|armhf) PKG_ARCH="armv7" ;;
    *) err "Arhitectura $ARCH nu este suportata."; exit 1 ;;
esac
ok "Arhitectura: $ARCH ($PKG_ARCH)"

DISTRO=""
if [[ -f /etc/os-release ]]; then
    . /etc/os-release
    DISTRO="${ID,,}"
    DISTRO_LIKE="${ID_LIKE:-}"
fi

PKG_FORMAT=""
INSTALL_CMD=""
case "$DISTRO" in
    ubuntu|debian|linuxmint|pop|elementary|kali|raspbian)
        PKG_FORMAT="deb"; INSTALL_CMD="apt-get install -y" ;;
    fedora|rhel|centos|rocky|almalinux|nobara)
        PKG_FORMAT="rpm"; INSTALL_CMD="dnf install -y" ;;
    opensuse-leap|opensuse-tumbleweed|opensuse|sles|suse)
        PKG_FORMAT="rpm-suse"; INSTALL_CMD="zypper install --no-confirm" ;;
    arch|manjaro|endeavouros|garuda)
        PKG_FORMAT="appimage"; INSTALL_CMD="" ;;  # Arch via AppImage (mai sigur)
    *)
        # Fallback prin ID_LIKE
        case "$DISTRO_LIKE" in
            *debian*|*ubuntu*) PKG_FORMAT="deb"; INSTALL_CMD="apt-get install -y" ;;
            *rhel*|*fedora*) PKG_FORMAT="rpm"; INSTALL_CMD="dnf install -y" ;;
            *suse*) PKG_FORMAT="rpm-suse"; INSTALL_CMD="zypper install --no-confirm" ;;
            *) PKG_FORMAT="appimage" ;;
        esac
        ;;
esac
ok "Distro: $DISTRO -> format $PKG_FORMAT"

# === Construire URL download ================================================
BASE_URL="https://github.com/rustdesk/rustdesk/releases/download/${RUSTDESK_VERSION}"
case "$PKG_FORMAT" in
    deb)        ASSET="rustdesk-${RUSTDESK_VERSION}-${PKG_ARCH}.deb" ;;
    rpm)        ASSET="rustdesk-${RUSTDESK_VERSION}-0.${PKG_ARCH}.rpm" ;;
    rpm-suse)   ASSET="rustdesk-${RUSTDESK_VERSION}-0.${PKG_ARCH}-suse.rpm" ;;
    appimage)   ASSET="rustdesk-${RUSTDESK_VERSION}-${PKG_ARCH}.AppImage" ;;
esac
URL="${BASE_URL}/${ASSET}"
TMP="/tmp/${ASSET}"

# === Descarca + instaleaza ==================================================
step "Descarc RustDesk ${RUSTDESK_VERSION} (${ASSET})..."
if ! curl -fLsS --connect-timeout 15 -o "$TMP" "$URL"; then
    err "Download esuat: $URL"; exit 1
fi
ok "Descarcat: $(du -h "$TMP" | cut -f1)"

step "Instalez RustDesk..."
case "$PKG_FORMAT" in
    deb)
        if ! dpkg -i "$TMP" 2>/dev/null; then
            warn "dpkg a esuat (probabil dependinte lipsa), incerc apt-get -f install..."
            apt-get install -y -f
            dpkg -i "$TMP"
        fi
        ;;
    rpm|rpm-suse)
        $INSTALL_CMD "$TMP"
        ;;
    appimage)
        mkdir -p /opt/rustdesk
        cp "$TMP" /opt/rustdesk/rustdesk.AppImage
        chmod +x /opt/rustdesk/rustdesk.AppImage
        # Symlink pentru CLI access
        ln -sf /opt/rustdesk/rustdesk.AppImage /usr/local/bin/rustdesk
        # Desktop file
        cat > /usr/share/applications/rustdesk.desktop <<EOF
[Desktop Entry]
Name=Rosistem Remote Support
Comment=Remote desktop
Exec=/opt/rustdesk/rustdesk.AppImage
Icon=rustdesk
Terminal=false
Type=Application
Categories=Network;RemoteAccess;
EOF
        ;;
esac
ok "RustDesk instalat."

rm -f "$TMP"

# === Genereaza parola unica =================================================
gen_password() {
    local len=16
    local alpha="ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789"
    local pwd=""
    for ((i=0; i<len; i++)); do
        pwd+="${alpha:RANDOM%${#alpha}:1}"
    done
    echo "$pwd"
}
PASSWORD=$(gen_password)

# === Configureaza RustDesk ==================================================
# RustDesk pe Linux citeste config-ul din locul standard de service:
#   /root/.config/rustdesk/RustDesk2.toml   (cand ruleaza ca serviciu)
# si din user home pentru rularea ne-service.
# Folosim CLI: rustdesk --option ... (scrie in locul corect automat)
step "Configurare server + cheie + parola..."

RD_BIN=""
for cand in /usr/bin/rustdesk /usr/local/bin/rustdesk /opt/rustdesk/rustdesk /opt/rustdesk/rustdesk.AppImage; do
    [[ -x "$cand" ]] && RD_BIN="$cand" && break
done
[[ -z "$RD_BIN" ]] && { err "Nu gasesc executabilul rustdesk."; exit 1; }
ok "RustDesk binary: $RD_BIN"

# Aplica configul (rustdesk merge in foreground daca-l rulam fara optiuni;
# cu --option scrie config + iese)
"$RD_BIN" --option custom-rendezvous-server "$SERVER_HOST" 2>/dev/null || true
"$RD_BIN" --option key                       "$SERVER_KEY"  2>/dev/null || true
"$RD_BIN" --option relay-server              "$SERVER_HOST" 2>/dev/null || true
"$RD_BIN" --option api-server                "$API_URL"     2>/dev/null || true
"$RD_BIN" --password "$PASSWORD" 2>/dev/null || true
sleep 2

# === Porneste serviciul =====================================================
step "Pornire serviciu rustdesk..."
if systemctl list-unit-files 2>/dev/null | grep -q "^rustdesk\.service"; then
    systemctl enable --now rustdesk 2>/dev/null || true
    ok "Serviciu rustdesk activ + boot."
else
    warn "Serviciu rustdesk nu exista (AppImage install). Pornesc in background..."
    nohup "$RD_BIN" --service >/var/log/rustdesk.log 2>&1 &
fi
sleep 3

# === Citeste ID-ul ==========================================================
step "Astept ID-ul RustDesk..."
RD_ID=""
for i in {1..20}; do
    sleep 2
    OUT=$("$RD_BIN" --get-id 2>/dev/null || echo "")
    CANDIDATE=$(echo "$OUT" | tr -d -c '0-9' | head -c 12)
    if [[ ${#CANDIDATE} -ge 7 ]]; then RD_ID="$CANDIDATE"; break; fi
done

# Fallback: citeste din TOML
if [[ -z "$RD_ID" ]]; then
    for toml in /root/.config/rustdesk/RustDesk.toml /var/lib/rustdesk/.config/rustdesk/RustDesk.toml $HOME/.config/rustdesk/RustDesk.toml; do
        if [[ -f "$toml" ]]; then
            RD_ID=$(grep -E '^id\s*=' "$toml" | head -1 | sed -E 's/.*"([^"]+)".*/\1/' || true)
            [[ -n "$RD_ID" ]] && break
        fi
    done
fi

if [[ -n "$RD_ID" ]]; then ok "ID RustDesk: $RD_ID"; else warn "Nu am putut citi ID-ul automat."; fi

# === Enrollment =============================================================
step "Anunt panoul Rosistem despre acest PC..."
HOSTNAME_VAL=$(hostname 2>/dev/null || echo "unknown")
OS_VAL="Linux $(. /etc/os-release 2>/dev/null && echo "${PRETTY_NAME:-$DISTRO}")"
INSTALL_USER="${SUDO_USER:-$(whoami)}"

PAYLOAD=$(printf '{"id":"%s","password":"%s","hostname":"%s","computer_name":"%s","install_user":"%s","os":"%s","agent_version":"%s"}' \
    "$RD_ID" "$PASSWORD" "$HOSTNAME_VAL" "$HOSTNAME_VAL" "$INSTALL_USER" "$OS_VAL" "$RUSTDESK_VERSION")

if HTTP_CODE=$(curl -s -o /tmp/enroll.resp -w "%{http_code}" \
    -X POST "$ENROLL_URL" \
    -H "Content-Type: application/json" \
    -H "X-Enroll-Secret: $ENROLL_SECRET" \
    --connect-timeout 10 --max-time 30 \
    -d "$PAYLOAD"); then
    if [[ "$HTTP_CODE" == "200" ]]; then
        ok "Inrolat. Rosistem Support va vedea acest PC in panou."
    else
        err "Server enrollment a refuzat (HTTP $HTTP_CODE): $(cat /tmp/enroll.resp 2>/dev/null)"
        warn "RustDesk e instalat si configurat - ID: $RD_ID"
    fi
    rm -f /tmp/enroll.resp
else
    err "Inrolare esuata (problema retea?). RustDesk ramane instalat - ID: $RD_ID"
fi

# === Final ==================================================================
echo ""
echo "==================================================="
echo -e " ${C_GREEN}GATA. Calculatorul este pregatit pentru suport.${C_NC}"
echo "==================================================="
echo " Nu trebuie sa faci nimic in continuare."
echo " Rosistem Support va vedea acest PC online cand are nevoie."
echo ""
