#!/bin/bash

#Этот скрипт -- неофициальное решение от АСКОН для установки КОМПАС-3D и всех компонентов, включая Библиотеку Стандартных Изделий, на Ubuntu 24.04.
#Обратите внимание, что КОМПАС-3D для Linux официально поддерживается только на трёх операционных системах: Astra Linux Special Edition 1.8, Альт Рабочая Станция 11 / К11 и РЕД ОС 8. 
#Используйте, редактируйте и распространяйте этот скрипт на свой страх и риск.

set -euo pipefail

# Цвета
RED=$'\033[0;31m'
YELLOW=$'\033[1;33m'
NC=$'\033[0m'

#Проверка на root
if [[ $EUID == 0 ]]; then
    echo "${RED}ВНИМАНИЕ: Скрипт предназначен и протестирован для запуска от обычного пользователя. Запуск скрипта от суперпользователя может иметь непредвиденные последствия. Пожалуйста, перезапустите скрипт от обычного пользователя без sudo."
    exit 1
fi

# Создание рабочих директорий и файла логирования
WORKDIR="/tmp/kompas-install"
DOWNLOAD_DIR="$WORKDIR/downloads"
EXTRACT_DIR="$WORKDIR/extracted"
LOGS="$WORKDIR/$(date '+%Y-%m-%d_%H-%M-%S').log"

for dir in "$WORKDIR" "$DOWNLOAD_DIR" "$EXTRACT_DIR"; do
    mkdir -p "$dir" || { echo "Не удаётся создать рабочий каталог: $dir" >&2; exit 1; }
done

touch "$LOGS"
: > "$LOGS" 2>/dev/null || { echo "Ошибка создания или записи файла логирования $LOGS" >&2; exit 1; }

# Задаём функции логирования
log() {
    local TIMESTAMP=$(date '+%T');
    echo "[$TIMESTAMP] $*" | tee -a "$LOGS";
}

warn() {
    local TIMESTAMP=$(date '+%T');
    echo "${YELLOW}[$TIMESTAMP] ВНИМАНИЕ: $*${NC}";
    echo -e "[$TIMESTAMP] ВНИМАНИЕ:\n$*\n---------------------" &>> "$LOGS";
}

error() {
    local TIMESTAMP=$(date '+%T');
    echo "${RED}[$TIMESTAMP] ОШИБКА: $*${NC}";
    echo "${RED}Файл логирования доступен для изучения по пути: $LOGS${NC}";
    echo -e "[$TIMESTAMP] ОШИБКА:\n$*\n-------------------" &>> "$LOGS";
    exit 1
}

#Функция вопроса
ask() {
    echo -n "$* (y/n): " | tee -a "$LOGS" || warn "Ошибка записи в лог";
    local answer
    while true
    do
        read -r answer || return 1
        case "$answer" in
            [Yy]|[Yy][Ee][Ss]|[Дд]|[Дд][Аа])
                echo "Ответ: да" >> "$LOGS" || warn "Ошибка записи в лог"
                return 0 ;;
            [Nn]|[Nn][Oo]|[Нн]|[Нн][Ее][Тт])
                echo "Ответ: нет" >> "$LOGS" || warn "Ошибка записи в лог"
                return 1 ;;
            *) echo -n "Некорректный ввод. $* (y/n): " | tee -a "$LOGS" || warn "Ошибка записи в лог";;
        esac
    done
}

#Функция проверки дистрибутива
check_dist() {
    if [[ -f /etc/os-release ]]; then
        . /etc/os-release
        if [[ "$ID" != "ubuntu" ]] || [[ "$VERSION_ID" != "24.04" ]]; then
            warn "Кажется, вы используете $PRETTY_NAME в качестве операционной системы. Данный скрипт написан и протестирован для Ubuntu 24.04."
            ask "Продолжить установку на $PRETTY_NAME?" || error "Установка прервана пользователем."
        fi
    else
        warn "Не удаётся определить версию дистрибутива. Данный скрипт написан и протестирован для Ubuntu 24.04"
        ask "Продолжить с неизвестным дистрибутивом?" || error "Установка прервана пользователем."
    fi
}

#Функция проверки свободного пространства на диске
check_space() {
    if (( $(df /opt/ --output=avail --block-size=1G | tail -1) < 75 || $(df /tmp/ --output=avail --block-size=1G | tail -1) < 70 )); then
        warn "В целевой папке недостаточно свободного места. Скорее всего, установка пройдёт неудачно. Для установки рекомендуется иметь не менее 75 Гб свободного дискового пространства в директории /opt и не менее 70 Гб в директории /tmp."
        ask "Продолжить установку?" || error "Установка прервана пользователем."
    fi
}

#Функция загрузки файла
download() {
    local url
    local rc=0
    for url in "$@"; do
        log "Скачивается: $url"
        wget -t 10 --show-progress -c -nc -P "$DOWNLOAD_DIR" "$url" || { warn "Ошибка скачивания файла: $url. Скрипт будет аварийно остановлен после загрузки остальных файлов."; rc=1; }
    done
    if (( rc != 0 )); then
        error "Ошибка скачивания"
    fi
}

#Функция подключения репозитория КОМПАС-3D
add_repo(){
    local add_main=0
    local add_personal=0
    local version=$1
    if [[ "$version" == "ascon-kompas3d-v25-full" ]]; then
        if [[ -f /etc/apt/sources.list.d/ascon.list ]]; then
            if ask "Обнаружен файл репозитория АСКОН. Обновить репозиторий?"; then
                add_main=1
            fi
        else
            add_main=1
        fi
    else
        if [[ -f /etc/apt/sources.list.d/ascon-personal.list || -f /etc/apt/sources.list.d/ascon.list ]]; then
            if ask "Обнаружены файлы репозиториев АСКОН. Обновить репозитории?"; then
                add_main=1
                add_personal=1
            fi
        else
            add_main=1
            add_personal=1
        fi
    fi
    if (( add_main )); then
        sudo bash -c "$(wget -O - https://repo.ascon.ru/scripts/ascon-stable-deb.sh)" || true
        echo "deb [signed-by=/etc/apt/trusted.gpg.d/ascon.gpg] https://repo.ascon.ru/stable/deb 1.8_x86-64 main" | sudo tee /etc/apt/sources.list.d/ascon.list >/dev/null || warn "Не удалось отредактировать файл основного репозитория АСКОН"
    fi
    if (( add_personal )); then
        sudo bash -c "$(wget -O - https://repo.ascon.ru/personal/scripts/ascon-personal-deb.sh)" || true
        echo "deb [signed-by=/etc/apt/trusted.gpg.d/ascon.gpg] https://repo.ascon.ru/personal/deb 1.8_x86-64 main" | sudo tee /etc/apt/sources.list.d/ascon-personal.list >/dev/null || warn "Не удалось отредактировать файл некоммерческого репозитория АСКОН"
    fi
    sudo apt update || warn "Ошибка получения метаданных пакетов. Возможно, репозиторий сконфигурировался некорректно."
}

#Первичная настройка и предупреждения
log "Этот скрипт установит КОМПАС-3D и все доступные библиотеки на Ubuntu 24.04. Обратите внимание, что КОМПАС-3D официально  поддерживается только на операционных системах Astra Linux Special Edition 1.8, Альт Рабочая Станция 11/К11 и РЕД ОС 8. Данный скрипт является неофициальным решением, использует множество костылей и поставляется "как есть". Продолжая, вы подтверждаете, что осознаёте вероятность негативного влияния этого скрипта на вашу систему и принимаете риск."
ask "Подтвердите продолжение" || error "Установка прервана пользователем."

check_dist
check_space

KOMPAS_VERSION=ascon-kompas3d-v25-full

while true; do
    echo "Выберите необходимую версию КОМПАС-3D [1]:" | tee -a "$LOGS" || warn "Ошибка записи в лог"
    echo "  1) КОМПАС-3D v25 (коммерческая) - вариант по умолчанию" | tee -a "$LOGS" || warn "Ошибка записи в лог"
    echo "  2) КОМПАС-3D v25 Home (домашняя)" | tee -a "$LOGS" || warn "Ошибка записи в лог"
    echo "  3) КОМПАС-3D v25 Study (учебная)" | tee -a "$LOGS" || warn "Ошибка записи в лог"
    read -r answer || error "Не удалось считать ответ"
    case "$answer" in
    "" | 1)
        break
        ;;
    2)
        KOMPAS_VERSION=ascon-kompas3d-home-v25-full
        break
        ;;
    3)
        KOMPAS_VERSION=ascon-kompas3d-study-v25-full
        break
        ;;
    *)
        echo "Некорректное значение."
        ;; 
    esac
    echo $KOMPAS_VERSION >> "$LOGS" || warn "Ошибка записи в лог"
done

#Установка дополнительных пакетов
sudo apt update || warn "Ошибка получения метаданных пакетов."
sudo apt install -y curl gnupg locales desktop-file-utils libxcb-res0 libxcb-xkb1 libxcb-xinput0 rpm2cpio cpio || error "Не удалось установить необходимые пакеты"

#Установка необходимых локалей
sudo sed -i 's/^# *\(ru_RU\.UTF-8 UTF-8\)/\1/' /etc/locale.gen || warn "Не удалось сгенерировать локали"
sudo sed -i 's/^# *\(en_US\.UTF-8 UTF-8\)/\1/' /etc/locale.gen || warn "Не удалось сгенерировать локали"
sudo locale-gen || warn "Не удалось сгенерировать локали"

#Подключение репозиториев и обновление метаданных
add_repo "$KOMPAS_VERSION"

#Установка КОМПАС-3D
log "Устанавливаем $KOMPAS_VERSION"
sudo apt install -y $KOMPAS_VERSION ascon-common-coredump-watcher || {
    warn "Похоже, что установка КОМПАС-3D через apt не удалась."
    if ask "Попробовать установить КОМПАС-3D, скачивая пакет Библиотеки Стандартных изделий через wget?"; then
        wget -t 10 --show-progress -c -nc -P "$DOWNLOAD_DIR" https://repo.ascon.ru/stable/deb/pool/main/a/ascon/ascon-polynom-library-24.0-24.0.0.26061516-amd64.deb || error "Не удалось скачать пакет Библиотеки Стандартных изделий"
        sudo apt install "$DOWNLOAD_DIR/ascon-polynom-library-24.0-24.0.0.26061516-amd64.deb" || error "Не удалось установить пакет Библиотеки Стандартных изделий"
        sudo apt install -y "$KOMPAS_VERSION" ascon-common-coredump-watcher || error "Не удалось установить КОМПАС-3D"
    else
        error "Не удалось установить КОМПАС-3D: пользователь отказался от ручного режима установки."
    fi
}

sudo rm -rf /opt/ascon/polynom-library || error "Не удалось очистить директорию polynom-library"

log "Установка Polynom из Альт 11..."
log "В качестве рабочей директории будет использована $WORKDIR"

ALT_BASE="https://repo.ascon.ru/stable/alt/p11/x86_64/RPMS.main"
RPM_URLS=(
    "$ALT_BASE/ascon-polynom-library-24.0-24.0.0.26061516-0.x86_64.rpm"
    "$ALT_BASE/ascon-polynom-library-database-part1-24.0-24.0.0.26051921-0.x86_64.rpm"
    "$ALT_BASE/ascon-polynom-library-database-part2-24.0-24.0.0.26051921-0.x86_64.rpm"
    "$ALT_BASE/ascon-polynom-library-database-part3-24.0-24.0.0.26051921-0.x86_64.rpm"
    "$ALT_BASE/ascon-polynom-library-database-part4-24.0-24.0.0.26051921-0.x86_64.rpm"
    "$ALT_BASE/ascon-polynom-library-database-part5-24.0-24.0.0.26051921-0.x86_64.rpm"
)

log "Скачиваем и распаковываем .rpm-пакеты из репозитория для Альт РС 11..."
download "${RPM_URLS[@]}"
for rpm in "$DOWNLOAD_DIR"/*.rpm; do
    rpm2cpio "$rpm" | cpio -D "$EXTRACT_DIR" -idmv || warn "Ошибка извлечения архивов .rpm"
done

log "Переносим распакованную базу данных в директорию polynom..."
sudo mv "$EXTRACT_DIR/opt/ascon/polynom-library" "/opt/ascon/" || error "Не удалось перенести новую базу данных в необходимое место"

log "Устанавливаем права в Библиотеке Стандартных изделий..."
sudo chown -R root:root /opt/ascon/polynom-library || error "Не удалось установить права"
sudo chmod -R 775 /opt/ascon/polynom-library || error "Не удалось установить права"
sudo chown -R polynom:root /opt/ascon/polynom-library/database || error "Не удалось установить права"
sudo chmod -R 750 /opt/ascon/polynom-library/database || error "Не удалось установить права"

log "Запускаем службу Библиотеки Стандартных изделий..."
#sudo systemctl restart polynompg.service
sudo systemctl restart polynomlib.service

log "Установка завершена."
if ask "В процессе установки было использовано много дополнительного пространства. Очистить рабочую директорию?"; then
    rm -rf $WORKDIR
fi

if ask "Рекомендуется перезапустить систему после установки. Начать перезагрузку?"; then
    sudo reboot
fi