#!/bin/bash -e

#┌────────────────────────────────────────────────────────────────────────────┐
#│  Если вместо запуска установщика данный файл открывается в текстовом       │
#│    редакторе, откройте командную консоль и выполните команду               │
#│      chmod +x install_firesecnt.sh                                         │
#│  Или откройте в файловом менеджере свойства файла install_firesecnt.sh     │
#│    и установите право на выполнение файла (бит "x")                        │
#└────────────────────────────────────────────────────────────────────────────┘


me=$(basename "$0")

# Constants
SCRIPT_VERSION="3.0"
PKG_BASE="firesecnt"
PKG_COMMON="common"
PKG_BIN="bin"
PKG_DRV_R3LN="r3ln"
PKG_DRV_2OP3="2op3"
PKG_BNDL_ALL="all"
PKG_BNDL_SRV="server"
PKG_BNDL_DRV="driver"

# Colors
CCLR_RED='\033[1;31m'
CCLR_GRN='\033[1;32m'
CCLR_YLW='\033[1;33m'
CCLR_BLU='\033[1;34m'
CCLR_CLR='\033[0m'

GPG_ASTRA_KEY_FILE="/etc/digsig/keys/rubezh_pub.key"
GPG_ASTRA_KEY_CONTENT="-----BEGIN PGP ARMORED FILE-----
Comment: Use gpg --dearmor for unpacking

mN4EZGcyBCMBAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQxAAMHAP9f
v/SYqpOM5zm44CL7r+9AVj9uajRy/CpRTAzp2uI7fgACAgD8COKooOZRR9S9YxYD
DhbRnIXJfwqcomcSK5arvOp+j8gAAQEBAIAAAAAAAAAAAAAAAAAAAAFQ/ooYkpdh
VMWc/Bk6zPWzAP9LXLSix5LbV0qNBJU+zEyCzanKLKnP93vTmX/SM11oQAD8DayJ
RKnDL3i4elNZUO25oKKvQNWsHWMnsgesb3/AHJYAAQG0ONCe0J7QniAi0KDRg9Cx
0LXQtiIgKGtleSBmb3Igc2lnbmluZykgPHJ1YmV6aEBydWJlemgucnU+iJAEEyMM
ADgWIQRvMOxI1RXduorsk/ZKvgPl2VJJIAUCZGcyBAIbAwULCQgHAgYVCAkKCwIE
FgIDAQIeAQIXgAAKCRBKvgPl2VJJIM5GAP9e7p60q0Bw9P9N5vY7uSn/H53xjY/9
RvS0QSBcItUy9gD+KeT3SC76+UEmo/o8YKT6DTAYOH2TdhxzzORal9r8+w2IdQQQ
IwwAHRYhBKEte1uvzkDYf9Qdr8gtSfw2dbb6BQJkZzIEAAoJEMgtSfw2dbb6eL0A
/ir7pClgVwtWu8ZfpsCQ0p3gIxibGgbVHSOX4/e/i8tzAP42xOSVP1KeRW1F3QlJ
GqGGKFGIazywYjuKP7n7aaJtgA==
=j2zg
-----END PGP ARMORED FILE-----
"

function help() {
    echo " Запуск:"
    echo " sudo bash $me [опции]"
    echo
    echo " Опции:"
    echo "  -h                          вывести подсказку."
    echo "  -v                          отобразить версию скрипта."
    echo "  -q                          запуск в командном режиме, используются указанные опции"
    echo "                                  без ключа -q параметры установки будут запрошены в интерактивном режиме"
    echo "  -b [server, driver, all]    состав установки. server - все компоненты системы без драйвера. driver - только драйвер. По умолчанию - all."
    echo "  -d [r3ln, 2op3]             тип драйвера. Не используется совместно с -b server. По умолчанию - r3ln."
    echo "  -t [hu, hd, hr]             тип репозитория: user, dev, release соответственно. По умолчанию hr."
    echo "                                  репозитории user и dev не доступны из сети интернет."
    echo "  -r <version>                версия пакета. Допустимо указывать неполную версию со звездочкой в конце (например: 1.8*)."
    echo
    echo "Примеры:"
    echo
    echo "            sudo bash $me"
    echo "Будет установлен пакет с последней стабильной версией ПО FireSecNT с поддержкой оборудования линейки R3 с интерфейсом R3Link."
    echo
    echo "            sudo bash $me -d $PKG_DRV_R3LN"
    echo "Равносильно команде из предыдущего примера (пакет $PKG_DRV_R3LN выбирается по умолчанию, если не указан ключ -d)."
    echo
    echo "            sudo bash $me -d $PKG_DRV_2OP3"
    echo "Будет установлен пакет с последней стабильной версией ПО FireSecNT с поддержкой оборудования линейки R3 с интерфейсом 485."
    echo
    echo "            sudo bash $me -d $PKG_DRV_R3LN -r 1.8.14*"
    echo "Будет установлен пакет с 14-ой сборкой версии 1.8 ПО FireSecNT с поддержкой оборудования линейки R3 с интерфейсом R3Link."
    echo
    echo "            sudo bash $me -d $PKG_DRV_2OP3 -r 1.8*"
    echo "Будет установлен пакет с последней стабильной сборкой версии 1.8 ПО FireSecNT с поддержкой оборудования линейки R3 с интерфейсом 485."
    echo
}

version() {
    echo " Версия $me: $SCRIPT_VERSION"
}


# Default arg values
FSNT_DRIVER=$PKG_DRV_R3LN
FSNT_BUNDLE="all"
FSNT_VERSION=""
REPO_TYPE="hr"
VISUAL_MODE=true

while getopts "hvqb:d:t:r:" opt
do
    case $opt in
        h) help; exit ;;
        v) version; exit;;
        q) VISUAL_MODE=false;;
        b) FSNT_BUNDLE=$OPTARG ;;
        d) FSNT_DRIVER=$OPTARG ;;
        t) REPO_TYPE=$OPTARG ;;
        r) FSNT_VERSION=$OPTARG ;;
        *) help; exit 1 ;;
    esac
done

if [[ $EUID -ne 0 ]]
    then echo -e "${CCLR_YLW}Перезапуск скрипта от имени суперпользователя...${CCLR_CLR}"
    exec sudo bash "$0" "$@"
    exit
fi

# Убьем авто-обновление, если оно запущено
# Сначала отправляем сигнал TERM для корректного завершения
pkill -f ".*unattended.*" 2>/dev/null
# Даем процессам время на корректное завершение
timeout=3
end_time=$(( $(date +%s) + timeout ))
while [ $(date +%s) -lt $end_time ]; do
    if ! pgrep -f ".*unattended.*" >/dev/null; then
        break
    fi
    sleep 0.2
done
# Если процессы еще остались, принудительно убиваем их
pkill -9 -f ".*unattended.*" 2>/dev/null
# Проверяем, есть ли пакеты, требующие настройки
if dpkg -l | grep -q "^iU"; then
    echo -e "${CCLR_BLU}Настраиваем пакеты...${CCLR_CLR}"
    DEBIAN_FRONTEND=noninteractive timeout 60 dpkg --configure -a 2>/dev/null
fi

# Trap non-normal exit signals:
# shellcheck disable=SC2317
function err_handler {
    local exit_status=$?
    local last_command="${BASH_COMMAND}"
    local current_line="${BASH_LINENO[0]}"
    # Запрещаем рекурсию при ошибках в обработчике
    trap '' ERR
    if [[ "$last_command" =~ whiptail ]] && [[ $exit_status -eq 1 || $exit_status -eq 255 ]]; then
        echo -e "${CCLR_RED}Пользователь прервал установку${CCLR_CLR}" >&2
    else
        echo -e "${CCLR_RED}ERROR: script ${CCLR_YLW}'${BASH_SOURCE[0]}'${CCLR_RED} error code ${CCLR_YLW}${exit_status} ${CCLR_RED}at line${CCLR_CLR} $current_line: '$last_command'" >&2
    fi
    # Восстанавливаем trap
    trap err_handler ERR
    exit "$exit_status"
}
# Устанавливаем trap после определения функции
trap err_handler ERR


# Check CPU compatibility with MongoDB 5.0 (https://www.mongodb.com/docs/manual/administration/production-notes/)
if ! lscpu | grep -q avx; then
  echo -e "${CCLR_RED}ERROR: процессор вашей системы не удовлетворяет требованиям совместимости. Для FireSecNT требуется поддержка инструкций avx (см. https://en.wikipedia.org/wiki/Advanced_Vector_Extensions#CPUs_with_AVX).${CCLR_CLR}";
  exit 1;
fi

function ResolvePackageName()
{
    local bundle="$1"
    local driver="$2"
    case "$bundle" in
        "$PKG_BNDL_SRV")
            echo "${PKG_BASE}-${PKG_BNDL_SRV}"
        ;;
        "$PKG_BNDL_ALL" | "$PKG_BNDL_DRV")
            case "$driver" in
                "$PKG_DRV_R3LN" | "$PKG_DRV_2OP3") ;;
                *) echo -e "${CCLR_RED}Ошибка: неизвестный тип драйвера $driver${CCLR_CLR}" >&2; exit 1 ;;
            esac
            if [[ "$bundle" == "$PKG_BNDL_DRV" ]]; then
                echo "${PKG_BASE}-${PKG_BNDL_DRV}-${driver}"
            elif [[ "$bundle" == "$PKG_BNDL_ALL" ]]; then
                echo "${PKG_BASE}-${driver}"
            fi
        ;;
        *) echo -e "${CCLR_RED}Ошибка: неизвестный вид установки $bundle${CCLR_CLR}" >&2; exit 1 ;;
    esac
}

GetDependencyNames() {
    local bundle="$1" version="$2" driver="$3" result_var="$4"
    
    local -n result_ref="$result_var"
    result_ref=()

    case "$bundle" in
        "$PKG_BNDL_ALL")
            result_ref=(
                "${PKG_BASE}-${PKG_COMMON}=$version"
                "${PKG_BASE}-${PKG_BNDL_SRV}-${PKG_BIN}=$version"
                "${PKG_BASE}-${PKG_BNDL_SRV}=$version"
                "${PKG_BASE}-${PKG_BNDL_DRV}-${PKG_BIN}-${driver}=$version"
                "${PKG_BASE}-${PKG_BNDL_DRV}-${driver}=$version"
                "${PKG_BASE}-${driver}=$version"
            ) ;;
        "$PKG_BNDL_SRV")
            result_ref=(
                "${PKG_BASE}-${PKG_COMMON}=$version"
                "${PKG_BASE}-${PKG_BNDL_SRV}-${PKG_BIN}=$version"
                "${PKG_BASE}-${PKG_BNDL_SRV}=$version"
            ) ;;
        "$PKG_BNDL_DRV")
            result_ref=(
                "${PKG_BASE}-${PKG_COMMON}=$version"
                "${PKG_BASE}-${PKG_BNDL_DRV}-${PKG_BIN}-${driver}=$version"
                "${PKG_BASE}-${PKG_BNDL_DRV}-${driver}=$version"
            ) ;;
        *)
            echo -e "${CCLR_RED}Ошибка: неизвестный вид установки $bundle${CCLR_CLR}" >&2
            return 1 ;;
    esac
    return 0
}

function ResetRepository()
{
    local repo_name="$1"
    cp /dev/null "/etc/apt/sources.list.d/${repo_name}.list"
}

function AddRepository()
{
    local pubkey_url="$1"
    local repository_url="$2"
    local repository_distrib="$3"
    local repo_name="$4"

    local keyring_dir="/usr/share/keyrings"
    mkdir -p "${keyring_dir}"
    curl -fsSL "${pubkey_url}" | gpg --yes -o "${keyring_dir}/${repo_name}.gpg" --dearmor

    echo "deb [ signed-by=${keyring_dir}/${repo_name}.gpg ] ${repository_url} ${repository_distrib} main" | \
            tee -a "/etc/apt/sources.list.d/${repo_name}.list"
}

function AddUnsignedRepository()
{
    local repository_url="$1"
    local repository_distrib="$2"
    local repo_name="$3"

    echo "deb ${repository_url} ${repository_distrib} main contrib non-free" | \
            tee "/etc/apt/sources.list.d/${repo_name}.list"
}

function InstallDeb()
{
    local packages=("$@")
    if ! apt-get install -y --allow-downgrades "${packages[@]}"; then
        echo -e "${CCLR_RED}Ошибка: не удалось установить пакет(ы) '${packages[*]}'. Проверьте соединение с интернетом.${CCLR_CLR}" >&2
        exit 1
    fi
}

function CheckAstraGPGKey()
{
    if astra-digsig-control is-enabled > /dev/null && [ ! -e $GPG_ASTRA_KEY_FILE ]; then
        echo -e "$CCLR_RED"
        echo "┌──────────────────────────────────────────────────────────────────────────────────────────────┐"
        echo "│                                     Включен резим ЗПС!                                       │"
        echo "│     Программа установки добавит ключ FireSecNT в ОС, после этого требуется перезагрузка!     │"
        echo "│     После перезагрузки запустите установку FireSecNT еще раз, установка будет продолжена     │"
        echo "│                      ─────────────────────────────────────────────────                       │"
        echo "│                       Дождитесь завершения процесса пересборки initrd                        │"
        echo "└──────────────────────────────────────────────────────────────────────────────────────────────┘"
        echo -e "$CCLR_CLR"
        echo "${GPG_ASTRA_KEY_CONTENT}" | gpg --dearmor > "${GPG_ASTRA_KEY_FILE}"
        update-initramfs -uk all
        echo -e "$CCLR_YLW"
        echo "┌──────────────────────────────────────────────────────────────────────────────────────────────┐"
        echo "│                                 Пересборка initrd завершена.                                 │"
        echo "│                                  Требуется перезагрузка ОС.                                  │"
        echo "└──────────────────────────────────────────────────────────────────────────────────────────────┘"
        echo -e "$CCLR_CLR"
        exit 2
    fi
}

function SetRabbitMQAddress()
{
    local rabbit_address="$1"
    [ -z "$rabbit_address" ] && return 1
    CONFIG_FILES=(
        "/etc/firesecnt/application.properties"
        # "/etc/firesecnt/application-${FSNT_DRIVER}.properties"
    )

    local replaced=0
    
    for config_file in "${CONFIG_FILES[@]}"; do
        [ -f "$config_file" ] || continue
        sed -i "s|^spring\.rabbitmq\.host=.*|spring.rabbitmq.host=$rabbit_address|" "$config_file" && replaced=1
        sed -i -E "s|^(rabbitmq\.api=http://)[^:]+(:[0-9]+/api/)|\1${rabbit_address}\2|g" "$config_file" && replaced=1
    done
    
    [ $replaced -eq 1 ] && return 0 || return 1
}

DEB_PACKAGE=$(ResolvePackageName "$FSNT_BUNDLE" "$FSNT_DRIVER")

#supported OS identifiers
declare -A OS_IDS
OS_IDS[astraSE17]="astra_1.7_x86-64"
OS_IDS[astraSE18]="astra_1.8_x86-64"
OS_IDS[deb10]="debian_10"
OS_IDS[deb9]="debian_9"
OS_IDS[astraCE]="astra_2.12.*"
OS_IDS[ub18]="ubuntu_18.04"

# import OS information
. /etc/os-release

CURRENT_OS_ID="${ID}_${VERSION_ID}"

# Remove previously used custom repositories
rm -f /etc/apt/sources.list.d/bellsoft*
rm -f /etc/apt/sources.list.d/mongodb*
rm -f /etc/apt/sources.list.d/firesecnt*
rm -f /etc/apt/sources.list.d/jre*

# Add Astra SE 1.7 internet repositories and remove CDROM
if [ "${CURRENT_OS_ID}" = "${OS_IDS[astraSE17]}" ]; then
    sed -i "s/deb cdrom/#deb cdrom/" /etc/apt/sources.list
    AddUnsignedRepository "https://download.astralinux.ru/astra/stable/1.7_x86-64/repository-main/" \
                              "1.7_x86-64" "astra_main"
    AddUnsignedRepository "https://download.astralinux.ru/astra/stable/1.7_x86-64/repository-update/" \
                              "1.7_x86-64" "astra_update"
    AddUnsignedRepository "https://download.astralinux.ru/astra/stable/1.7_x86-64/repository-base/" \
                              "1.7_x86-64" "astra_base"
    AddUnsignedRepository "https://download.astralinux.ru/astra/stable/1.7_x86-64/repository-extended/" \
                              "1.7_x86-64" "astra_extended"
    CheckAstraGPGKey
elif [ "${CURRENT_OS_ID}" = "${OS_IDS[astraSE18]}" ]; then
    sed -i "s/deb cdrom/#deb cdrom/" /etc/apt/sources.list
    AddUnsignedRepository "https://download.astralinux.ru/astra/stable/1.8_x86-64/repository-main/" \
                              "1.8_x86-64" "astra_main"
    AddUnsignedRepository "https://download.astralinux.ru/astra/stable/1.8_x86-64/repository-extended/" \
                              "1.8_x86-64" "astra_extended"
    CheckAstraGPGKey
fi

apt-get update || echo -e "${CCLR_RED}Предупреждение: не удалось произвести обновление списков пакетов${CCLR_CLR}"
InstallDeb apt-transport-https
InstallDeb curl
InstallDeb wget
if $VISUAL_MODE; then InstallDeb whiptail; fi

INNER_NEXUS_URL="http://nexus.rubezh.local:8081"
OUTER_NEXUS_URL="https://kb-nexus.rubezh.ru"

# Outer nexus is accessible on the port 7443 from the outside and from the default port from the inside
if ! wget -q -O /dev/null --spider "${OUTER_NEXUS_URL}"; then
    OUTER_NEXUS_URL="${OUTER_NEXUS_URL}:7443"
    echo -e "${CCLR_YLW}Информация: используется репозиторий ${OUTER_NEXUS_URL}${CCLR_CLR}"
fi

declare -A REPOSITORY_URLS
REPOSITORY_URLS[apt-firesecnt-bin-nosign-hr]=${OUTER_NEXUS_URL}
REPOSITORY_URLS[apt-firesecnt-bin-nosign-hd]=${INNER_NEXUS_URL}
REPOSITORY_URLS[apt-firesecnt-bin-nosign-hu]=${INNER_NEXUS_URL}
REPOSITORY_URLS[apt-firesecnt-bin-signastra-hr]=${OUTER_NEXUS_URL}
REPOSITORY_URLS[apt-firesecnt-bin-signastra-hd]=${INNER_NEXUS_URL}
REPOSITORY_URLS[apt-firesecnt-bin-signastra-hu]=${INNER_NEXUS_URL}
REPOSITORY_URLS[apt-firesecnt-astra18-hr]=${OUTER_NEXUS_URL}
REPOSITORY_URLS[apt-firesecnt-astra18-hd]=${INNER_NEXUS_URL}
REPOSITORY_URLS[apt-firesecnt-astra18-hu]=${INNER_NEXUS_URL}
REPOSITORY_URLS[apt-firesecnt-astra17-hr]=${OUTER_NEXUS_URL}
REPOSITORY_URLS[apt-firesecnt-astra17-hd]=${INNER_NEXUS_URL}
REPOSITORY_URLS[apt-firesecnt-astra17-hu]=${INNER_NEXUS_URL}
REPOSITORY_URLS[apt-firesecnt-deb12-hr]=${OUTER_NEXUS_URL}
REPOSITORY_URLS[apt-firesecnt-deb12-hd]=${INNER_NEXUS_URL}
REPOSITORY_URLS[apt-firesecnt-deb12-hu]=${INNER_NEXUS_URL}
REPOSITORY_URLS[apt-firesecnt-hr]=${OUTER_NEXUS_URL}
REPOSITORY_URLS[apt-firesecnt-hd]=${INNER_NEXUS_URL}
REPOSITORY_URLS[apt-firesecnt-hu]=${INNER_NEXUS_URL}
REPOSITORY_URLS[apt-firesecnt-deb9-hr]=${OUTER_NEXUS_URL}
REPOSITORY_URLS[apt-firesecnt-deb9-hd]=${INNER_NEXUS_URL}
REPOSITORY_URLS[apt-firesecnt-deb9-hu]=${INNER_NEXUS_URL}
REPOSITORY_URLS[apt-liberica-jre-17-signed]=${OUTER_NEXUS_URL}
REPOSITORY_URLS[apt-liberica-jre-17]=${OUTER_NEXUS_URL}
REPOSITORY_URLS[apt-mongodb-5-deb10-signed]=${OUTER_NEXUS_URL}
REPOSITORY_URLS[apt-mongodb-7-deb12-signed]=${OUTER_NEXUS_URL}
REPOSITORY_URLS[apt-mongodb-5-deb10]=${OUTER_NEXUS_URL}
REPOSITORY_URLS[apt-mongodb-5-deb9]=${OUTER_NEXUS_URL}
REPOSITORY_URLS[apt-mongodb-5-ub18]=${OUTER_NEXUS_URL}

# Set variables depending on the OS version
declare -A FSNT_REPOS
declare -A FSNT_REPOS_FILTER
# shellcheck disable=SC2254
case "${CURRENT_OS_ID}" in
    ${OS_IDS[astraSE17]}) FSNT_REPO_COUNT=3;
                          FSNT_REPOS["FSNT_REPO_0_NAME"]='apt-firesecnt-astra17';
                          FSNT_REPOS["FSNT_REPO_0_VER_FILTER"]='!/~signed/';
                          FSNT_REPOS_FILTER[apt-firesecnt-astra17]="${FSNT_VERSION}";
                          FSNT_REPOS["FSNT_REPO_1_NAME"]='apt-firesecnt';
                          FSNT_REPOS["FSNT_REPO_1_VER_FILTER"]='/~signed/';
                          FSNT_REPOS_FILTER[apt-firesecnt]="${FSNT_VERSION}~signed";
                          FSNT_REPOS["FSNT_REPO_2_NAME"]='apt-firesecnt-bin-signastra';
                          FSNT_REPOS["FSNT_REPO_2_VER_FILTER"]='!/~signed/';
                          JRE_REPO_NAME='apt-liberica-jre-17-signed';
                          MONGO_REPO_NAME='apt-mongodb-5-deb10-signed' ;;
    ${OS_IDS[astraSE18]}) FSNT_REPO_COUNT=3;
                          FSNT_REPOS["FSNT_REPO_0_NAME"]='apt-firesecnt-astra18';
                          FSNT_REPOS["FSNT_REPO_0_VERSION"]="${FSNT_VERSION}";
                          FSNT_REPOS["FSNT_REPO_0_VER_FILTER"]='!/~signed/';
                          FSNT_REPOS["FSNT_REPO_1_NAME"]='apt-firesecnt-deb12';
                          FSNT_REPOS["FSNT_REPO_1_VERSION"]="${FSNT_VERSION}~signed";
                          FSNT_REPOS["FSNT_REPO_1_VER_FILTER"]='/~signed/';
                          FSNT_REPOS["FSNT_REPO_2_NAME"]='apt-firesecnt-bin-signastra';
                          FSNT_REPOS["FSNT_REPO_2_VER_FILTER"]='!/~signed/';
                          JRE_REPO_NAME='apt-liberica-jre-17-signed';
                          MONGO_REPO_NAME='apt-mongodb-7-deb12-signed' ;;
    ${OS_IDS[deb10]}) FSNT_REPO_COUNT=2;
                          FSNT_REPOS["FSNT_REPO_0_NAME"]='apt-firesecnt';
                          FSNT_REPOS["FSNT_REPO_0_VERSION"]="${FSNT_VERSION}";
                          FSNT_REPOS["FSNT_REPO_0_VER_FILTER"]='!/~signed/';
                          FSNT_REPOS["FSNT_REPO_1_NAME"]='apt-firesecnt-bin-nosign';
                          FSNT_REPOS["FSNT_REPO_1_VER_FILTER"]='!/~signed/';
                          JRE_REPO_NAME='apt-liberica-jre-17';
                          MONGO_REPO_NAME='apt-mongodb-5-deb10' ;;
    ${OS_IDS[deb9]}) FSNT_REPO_COUNT=2;
                          FSNT_REPOS["FSNT_REPO_0_NAME"]='apt-firesecnt-deb9';
                          FSNT_REPOS["FSNT_REPO_0_VERSION"]="${FSNT_VERSION}";
                          FSNT_REPOS["FSNT_REPO_0_VER_FILTER"]='!/~signed/';
                          FSNT_REPOS["FSNT_REPO_1_NAME"]='apt-firesecnt-bin-nosign';
                          FSNT_REPOS["FSNT_REPO_1_VER_FILTER"]='!/~signed/';
                          JRE_REPO_NAME='apt-liberica-jre-17';
                          MONGO_REPO_NAME='apt-mongodb-5-deb9' ;;
    ${OS_IDS[astraCE]}) FSNT_REPO_COUNT=2;
                          FSNT_REPOS["FSNT_REPO_0_NAME"]='apt-firesecnt-deb9';
                          FSNT_REPOS["FSNT_REPO_0_VERSION"]="${FSNT_VERSION}";
                          FSNT_REPOS["FSNT_REPO_0_VER_FILTER"]='!/~signed/';
                          FSNT_REPOS["FSNT_REPO_1_NAME"]='apt-firesecnt-bin-nosign';
                          FSNT_REPOS["FSNT_REPO_1_VER_FILTER"]='!/~signed/';
                          JRE_REPO_NAME="apt-liberica-jre-17";
                          MONGO_REPO_NAME="apt-mongodb-5-deb9" ;;
    ${OS_IDS[ub18]}) FSNT_REPO_COUNT=2;
                          FSNT_REPOS["FSNT_REPO_0_NAME"]='apt-firesecnt-deb9';
                          FSNT_REPOS["FSNT_REPO_0_VERSION"]="${FSNT_VERSION}";
                          FSNT_REPOS["FSNT_REPO_0_VER_FILTER"]='!/~signed/';
                          FSNT_REPOS["FSNT_REPO_1_NAME"]='apt-firesecnt-bin-nosign';
                          FSNT_REPOS["FSNT_REPO_1_VER_FILTER"]='!/~signed/';
                          JRE_REPO_NAME='apt-liberica-jre-17';
                          MONGO_REPO_NAME='apt-mongodb-5-ub18';
        # For tomcat8. Remove on FSNT-22283.
        cat << EOF | tee /etc/default/tomcat8
JAVA_HOME=/usr/lib/jvm/bellsoft-java17-runtime-amd64
EOF
        ;;
    *) echo -e "${CCLR_RED}Операционная система ${CCLR_YLW}${ID} ${VERSION_ID}${CCLR_RED} не поддерживается${CCLR_CLR}"; exit 1;;
esac

# Greeting
if $VISUAL_MODE; then
    whiptail --title "Установщик FireSecNT" \
        --backtitle "Добро пожаловать в установщик FireSecNT" \
        --msgbox "Этот установщик поможет вам установить FireSecNT на вашу систему." 12 60
else
    echo -e "${CCLR_GRN}Добро пожаловать в установщик FireSecNT${CCLR_CLR}"
fi

# Repository selecting
INNER_NEXUS_AVAILABLE=$(wget -q -O /dev/null --spider "${INNER_NEXUS_URL}" && echo true || echo false)
if $INNER_NEXUS_AVAILABLE && $VISUAL_MODE; then
    options=("hr" "Стабильная версия" "hd" "Версия разработчиков" "hu" "Пользовательская сборка")
    REPO_TYPE=$(whiptail --title "Выбор репозитория" \
                    --backtitle "Установщик FireSecNT - Выбор репозитория" \
                    --default-item "$REPO_TYPE" \
                    --menu "Выберите тип репозитория:" 12 60 3 \
                    "${options[@]}" 3>&1 1>&2 2>&3)
fi
case "$REPO_TYPE" in
    hu) $VISUAL_MODE || echo -e "${CCLR_GRN}Информация: выбран user репозиторий${CCLR_CLR}";
        KEYPUB_NAME="public.apt-hu.key"; KEYPUB_REPO_NAME="raw_hu"; KEYPUB_REPO_URL="${INNER_NEXUS_URL}";
        REPO_DISTRIB="user"; FSNT_REPO_SUFFIX="-hu" ;;
    hd) $VISUAL_MODE || echo -e "${CCLR_GRN}Информация: выбран develop репозиторий${CCLR_CLR}";
        KEYPUB_NAME="public.apt-hd.key"; KEYPUB_REPO_NAME="raw_hd"; KEYPUB_REPO_URL="${INNER_NEXUS_URL}";
        REPO_DISTRIB="develop"; FSNT_REPO_SUFFIX="-hd" ;;
    hr) $VISUAL_MODE || echo -e "${CCLR_GRN}Информация: выбран release репозиторий${CCLR_CLR}";
        KEYPUB_NAME="public.apt-hr.key"; KEYPUB_REPO_NAME="raw_hr"; KEYPUB_REPO_URL="${OUTER_NEXUS_URL}";
        REPO_DISTRIB="release"; FSNT_REPO_SUFFIX="-hr" ;;
    *) echo -e "${CCLR_RED}Ошибка: не поддерживаемый тип репозитория ${REPO_TYPE}${CCLR_CLR}" >&2; exit 1 ;;
esac
if ! "$INNER_NEXUS_AVAILABLE" && [[ "$REPO_TYPE" != "hr" ]]; then\
    echo -e "${CCLR_YLW}Локальный репозиторий недоступен${CCLR_CLR}"
    exit 1
fi

# Add firesecnt repository
ResetRepository "firesecnt-repository"
for ((i=0; i<FSNT_REPO_COUNT; i++)); do
    FSNT_REPO_NAME="${FSNT_REPOS["FSNT_REPO_${i}_NAME"]}${FSNT_REPO_SUFFIX}"
    AddRepository "${KEYPUB_REPO_URL}/repository/${KEYPUB_REPO_NAME}/kb1/firesecnt/distrib/dpkg/apt_repo_keys/${KEYPUB_NAME}" \
                        "${REPOSITORY_URLS[$FSNT_REPO_NAME]}/repository/${FSNT_REPO_NAME}/" \
                        "${REPO_DISTRIB}" \
                        "firesecnt-repository"
done
# Add JRE repository
ResetRepository "jre-repository"
AddRepository "${OUTER_NEXUS_URL}/repository/raw_hr/kb1/firesecnt/distrib/dpkg/apt_repo_keys/public.apt-hr.key" \
                    "${REPOSITORY_URLS[$JRE_REPO_NAME]}/repository/${JRE_REPO_NAME}/" \
                    "release" \
                    "jre-repository"

# Add MongoDB repository
ResetRepository "mongodb-repository"
AddRepository "${OUTER_NEXUS_URL}/repository/raw_hr/kb1/firesecnt/distrib/dpkg/apt_repo_keys/public.apt-hr.key" \
                    "${REPOSITORY_URLS[$MONGO_REPO_NAME]}/repository/${MONGO_REPO_NAME}/" \
                    "release" \
                    "mongodb-repository"

apt-get update || echo -e "${CCLR_RED}Предупреждение: не удалось произвести обновление списков пакетов${CCLR_CLR}"

if $VISUAL_MODE; then
    # Component selecting
    options=("$PKG_BNDL_ALL" "Все компоненты" "$PKG_BNDL_SRV" "Серверные компоненты" "$PKG_BNDL_DRV" "Драйвер")
    FSNT_BUNDLE=$(whiptail --title "Выбор компонентов" \
                     --backtitle "Установщик FireSecNT - Выбор компонентов для установки" \
                     --default-item "$FSNT_BUNDLE" \
                     --menu "Выберите компоненты:" 20 60 10 \
                     "${options[@]}" 3>&1 1>&2 2>&3)
    menu_options=()
    # Driver selecting
    if [[ "$FSNT_BUNDLE" == "all" || "$FSNT_BUNDLE" == "driver" ]]; then
        options=("$PKG_DRV_R3LN" "Драйвер $PKG_DRV_R3LN" "$PKG_DRV_2OP3" "Драйвер $PKG_DRV_2OP3")
        FSNT_DRIVER=$(whiptail --title "Выбор драйвера" \
                        --backtitle "Установщик FireSecNT - Выбор драйвера" \
                        --default-item "$FSNT_DRIVER" \
                        --menu "Выберите тип драйвера для установки:" 12 60 2 \
                        "${options[@]}" 3>&1 1>&2 2>&3)
    fi
    # Determine package
    DEB_PACKAGE=$(ResolvePackageName "$FSNT_BUNDLE" "$FSNT_DRIVER")
    # Version selecting
    MNU_WIDTH=50
    for ((i=0; i<FSNT_REPO_COUNT; i++)); do
        FSNT_VER_FILTER="${FSNT_REPOS["FSNT_REPO_${i}_VER_FILTER"]} && /${FSNT_REPOS["FSNT_REPO_${i}_NAME"]}${FSNT_REPO_SUFFIX} /"
        for version in $(apt-cache madison "$DEB_PACKAGE" | awk "$FSNT_VER_FILTER { print \$3 }"); do
            menu_options+=("$version" "$version")
            if [ "${#version}" -gt "$MNU_WIDTH" ]; then MNU_WIDTH="${#version}"; fi
        done
    done
    MNU_WIDTH=$((MNU_WIDTH + 10))
    if [ ${#menu_options[@]} -eq 0 ]; then echo -e "${CCLR_RED}Нет подходящих версий!${CCLR_CLR}"; exit 1; fi
    FSNT_VERSION=$(whiptail --title "Выбор версии" \
                     --backtitle "Установщик FireSecNT - Выбор версии" \
                     --noitem \
                     --menu "Выберите версию для установки:" 20 "${MNU_WIDTH}" 10 \
                     "${menu_options[@]}" 3>&1 1>&2 2>&3)
else
    REPO_URL=$(apt-cache madison "$DEB_PACKAGE" | grep "$FSNT_VERSION" | awk "NR==1 { print \$5 }")
    REPO_FULL=${REPO_URL##*/}
    REPO=${REPO_FULL%"${FSNT_REPO_SUFFIX}"}
    FSNT_VERSION="${FSNT_VERSION}.*${FSNT_REPOS_FILTER[$REPO]}"
    FSNT_VERSION=$(apt-cache madison "$DEB_PACKAGE" | grep "$FSNT_VERSION" | awk "NR==1 { print \$3 }")
fi

echo -e "$CCLR_YLW"
echo "                                                                      ";
echo "███████╗██╗██████╗ ███████╗███████╗███████╗ ██████╗███╗   ██╗████████╗";
echo "██╔════╝██║██╔══██╗██╔════╝██╔════╝██╔════╝██╔════╝████╗  ██║╚══██╔══╝";
echo "█████╗  ██║██████╔╝█████╗  ███████╗█████╗  ██║     ██╔██╗ ██║   ██║   ";
echo "██╔══╝  ██║██╔══██╗██╔══╝  ╚════██║██╔══╝  ██║     ██║╚██╗██║   ██║   ";
echo "██║     ██║██║  ██║███████╗███████║███████╗╚██████╗██║ ╚████║   ██║   ";
echo "╚═╝     ╚═╝╚═╝  ╚═╝╚══════╝╚══════╝╚══════╝ ╚═════╝╚═╝  ╚═══╝   ╚═╝   ";
echo "                                                                      ";
echo -e "$CCLR_BLU"
echo "Установка FireSecNT. Пожалуйста, подождите..."
echo -e "$CCLR_CLR"

DEB_PACKAGE_EXPRESSION=${DEB_PACKAGE}=${FSNT_VERSION}
IS_MULTI_PACKAGE=true; [ "$(apt-cache depends "$DEB_PACKAGE_EXPRESSION" | grep -c "$PKG_BASE")" -gt 1 ] || IS_MULTI_PACKAGE=false
if $IS_MULTI_PACKAGE; then
    declare -a DEB_PACKAGE_LIST
    GetDependencyNames "$FSNT_BUNDLE" "$FSNT_VERSION" "$FSNT_DRIVER" DEB_PACKAGE_LIST
    InstallDeb "${DEB_PACKAGE_LIST[@]}"
else
    InstallDeb "$DEB_PACKAGE_EXPRESSION"
fi

if $VISUAL_MODE; then
    if [[ "$FSNT_BUNDLE" == "driver" ]]; then
        if RABBIT_ADDRESS=$(whiptail --title "Адрес хоста серверной части FireSecNT" \
                    --inputbox "Введите IP или доменное имя (при отказе от ввода настройка произведена не будет):" \
                    8 60 "127.0.0.1" \
                    3>&1 1>&2 2>&3); then
            if SetRabbitMQAddress "$RABBIT_ADDRESS"; then
                systemctl restart firesecnt-dr.service
            else
                whiptail --title "Ошибка установки параметра хоста" \
                    --msgbox "Не удалось обновить конфигурационный(е) файл(ы). Установите параметры хоста серверной части FireSecNT вручную" \
                    15 40
            fi
        fi
    fi
    whiptail --title "Установка завершена" \
        --msgbox "Установка FireSecNT завершена.\nПараметры установки:\n\nПакет:       $DEB_PACKAGE\nРепозиторий: $REPO_TYPE\nВерсия:      $FSNT_VERSION" \
        15 40 || true
fi
echo -e "$CCLR_YLW"
echo "                                                             ";
echo "███████╗██╗███╗   ██╗██╗███████╗██╗  ██╗███████╗██████╗ ██╗  ";
echo "██╔════╝██║████╗  ██║██║██╔════╝██║  ██║██╔════╝██╔══██╗██║  ";
echo "█████╗  ██║██╔██╗ ██║██║███████╗███████║█████╗  ██║  ██║██║  ";
echo "██╔══╝  ██║██║╚██╗██║██║╚════██║██╔══██║██╔══╝  ██║  ██║╚═╝  ";
echo "██║     ██║██║ ╚████║██║███████║██║  ██║███████╗██████╔╝██╗  ";
echo "╚═╝     ╚═╝╚═╝  ╚═══╝╚═╝╚══════╝╚═╝  ╚═╝╚══════╝╚═════╝ ╚═╝  ";
echo "                                                             ";
echo -e "$CCLR_CLR"
