#!/usr/bin/env bash
#
# Name: Software Installer
# Author: kleb
# Created: 2024/11/12
# Last modified: 2025/12/06
#
# Version: 1.2
#

set -euo pipefail

currentName="Software Installer"
currentVersion="1.2"
currentMe=$(basename "$0")

locationUtils="${BASE_URL:-https://kleb.sh}/installer/utils.sh"
locationVars="${BASE_URL:-https://kleb.sh}/installer/software/software.vars"

parentModule="${1:-}"

start() {
    source "utils.sh"

    trap clean ERR

    initProgress "Software" "$parentModule"
    logInfo "$currentName v$currentVersion"

    prepare
    execute
    clean
}

prepare() {
    updateProgress "Preparing Software module" 5

    if ! download "$locationVars" "software.vars" "${skipChecksum:-}"; then
        logError "Failed to download software.vars"
        return 1
    fi

    source "software.vars"

    updateProgress "Detecting system" 15

    osName=$(lsb_release -si)
    osName=${osName,,}
    osVersion=$(lsb_release -sc)
    osVersion=${osVersion,,}

    isLXC="FALSE"
    if [[ $(systemd-detect-virt) == "lxc" ]]; then
        isLXC="TRUE"
    fi

    serverHostname=$(hostname)
    if [[ ! "$serverHostname" =~ ^[A-Z] ]]; then
        serverHostname=$(getInput "What is the hostname?" "$serverHostname")
    fi

    if command -v ifconfig &>/dev/null; then
        ownIp=$(ifconfig | grep -Eo "inet (addr:)?([0-9]*\.){3}[0-9]*" | grep -Eo "([0-9]*\.){3}[0-9]*" | grep -v "127.0.0.1" | head -n 1)
    else
        ownIp=$(ip -4 addr show | awk '/inet / {print $2}' | cut -d/ -f1 | grep -v "127.0.0.1" | head -n 1)
    fi

    detectedDC=""
    zabbixServer=""
    zabbixPort=""

    if [[ "$ownIp" && -v ZABBIX_DCS ]]; then
        for dc in "${!ZABBIX_DCS[@]}"; do
            if [[ "$ownIp" == "${ZABBIX_DCS[$dc]}"* ]]; then
                detectedDC=$dc
                zabbixServer="${ZABBIX_SERVER[$dc]}"
                zabbixPort="${ZABBIX_PORT[$dc]:-10051}"
                serverHostname="${ZABBIX_HOSTNAME_PREFIX[$dc]}$serverHostname${ZABBIX_HOSTNAME_SUFFIX[$dc]}"

                logInfo "Using DC $dc"
                break
            fi
        done
    fi

    if [[ ! "$zabbixServer" ]]; then
        zabbixServer=$(getInput "Enter Zabbix Server/Proxy")
        zabbixPort=$(getInput "Enter Zabbix Port" "10051")
    fi
}

execute() {
    if [[ "${ZABBIX_AGENT:-}" == "TRUE" ]]; then
        updateProgress "Installing Zabbix Agent" 40

        if ! download "${ZABBIX_AGENT_URL}${osName}/${osVersion}/zabbix.deb" "zabbix.deb"; then
            logError "Failed to download Zabbix agent package"
            return 1
        fi

        if ! installPackage "zabbix.deb"; then
            logError "Failed to install Zabbix agent package"
            return 1
        fi

        noOut apt update
        if ! installPackage "$ZABBIX_AGENT_PACKAGE"; then
            logError "Failed to install Zabbix agent package: $ZABBIX_AGENT_PACKAGE"
            return 1
        fi

        updateProgress "Configuring Zabbix Agent" 45

        if ! replace "/etc/zabbix/zabbix_agentd.conf" "Server=127.0.0.1" "Server=$zabbixServer"; then
            logError "Failed to configure Zabbix Agent Server"
            return 1
        fi
        if ! replace "/etc/zabbix/zabbix_agentd.conf" "ServerActive=127.0.0.1" "ServerActive=$zabbixServer:$zabbixPort"; then
            logError "Failed to configure Zabbix Agent ServerActive"
            return 1
        fi
        if ! replace "/etc/zabbix/zabbix_agentd.conf" "Hostname=Zabbix server" "Hostname=$serverHostname"; then
            logError "Failed to configure Zabbix Agent Hostname"
            return 1
        fi

        enableService "zabbix-agent"
    fi

    if [[ "${ZABBIX_AGENT2:-}" == "TRUE" ]]; then
        updateProgress "Installing Zabbix Agent2" 55

        if ! download "${ZABBIX_AGENT2_URL}${osName}/${osVersion}/zabbix.deb" "zabbix.deb"; then
            logError "Failed to download Zabbix agent2 package"
            return 1
        fi

        if ! installPackage "zabbix.deb"; then
            logError "Failed to install Zabbix agent2 package"
            return 1
        fi

        noOut apt update
        if ! installPackage "$ZABBIX_AGENT2_PACKAGE"; then
            logError "Failed to install Zabbix agent2 package: $ZABBIX_AGENT2_PACKAGE"
            return 1
        fi

        updateProgress "Configuring Zabbix Agent2" 60

        if ! replace "/etc/zabbix/zabbix_agent2.conf" "Server=127.0.0.1" "Server=$zabbixServer"; then
            logError "Failed to configure Zabbix Agent2 Server"
            return 1
        fi
        if ! replace "/etc/zabbix/zabbix_agent2.conf" "ServerActive=127.0.0.1" "ServerActive=$zabbixServer:$zabbixPort"; then
            logError "Failed to configure Zabbix Agent2 ServerActive"
            return 1
        fi
        if ! replace "/etc/zabbix/zabbix_agent2.conf" "Hostname=Zabbix server" "Hostname=$serverHostname"; then
            logError "Failed to configure Zabbix Agent2 Hostname"
            return 1
        fi

        enableService "zabbix-agent2"
    fi

    if [[ "${ZABBIX_ADDON_APT:-}" == "TRUE" ]]; then
        updateProgress "Installing APT monitoring addon" 70

        if ! download "$ZABBIX_ADDON_APT_URL" "apt.sh" "${skipChecksum:-}"; then
            logError "Failed to download APT monitoring addon"
            return 1
        fi

        if [[ "$detectedDC" && -n "${ZABBIX_HOSTNAME_SUFFIX[$detectedDC]:-}" ]]; then
            sed -i "s/hostname=\"\$(hostname)\"/hostname=\"$(hostname)${ZABBIX_HOSTNAME_SUFFIX[$detectedDC]}\"/" "apt.sh"
        fi

        if ! move "apt.sh" "/usr/local/bin/apt.sh"; then
            logError "Failed to move apt.sh to /usr/local/bin/"
            return 1
        fi

        if ! installPackage "$ZABBIX_ADDON_APT_PACKAGE"; then
            logError "Failed to install APT monitoring addon package: $ZABBIX_ADDON_APT_PACKAGE"
            return 1
        fi

        cronjob="${ZABBIX_ADDON_APT_CRON//\{zbx_server\}/$zabbixServer}"
        if ! addCronjob "$cronjob"; then
            logError "Failed to add APT monitoring cron job"
            return 1
        fi
    fi

    if [[ "${ZABBIX_AGENT:-}" == "TRUE" ]]; then
        if [[ "${ZABBIX_ADDON_LXC:-}" == "TRUE" && "$isLXC" == "TRUE" ]]; then
            updateProgress "Installing LXC monitoring addon" 80

            if ! download "$ZABBIX_ADDON_LXC_URL" "container.conf"; then
                logError "Failed to download LXC monitoring addon"
                return 1
            fi

            if ! move "container.conf" "/etc/zabbix/zabbix_agentd.d/container.conf"; then
                logError "Failed to move container.conf to /etc/zabbix/zabbix_agentd.d/"
                return 1
            fi
        fi
    fi
}

clean() {
    remove "zabbix.deb"
    remove "software.vars"
    remove "$currentMe"

    updateProgress "Software module configuration complete" 100
}

start
