#!/usr/bin/env bash

# ============================================================================
# debian-nvidia-installer - NVIDIA Driver Installer for Debian (TUI)
# Copyright (C) 2025 Leonardo Amaral
#
# SPDX-License-Identifier:
#     GPL-3.0-or-later
#
# Module:
#     debian-nvidia-installer.sh
#
# Description:
#     Main file.
# ============================================================================




# ============================================================================
# Safety Checks
# ============================================================================
if [ -z "${BASH_VERSION:-}" ]; then
    echo "Error: This script must be run with Bash." >&2
    exit 1
fi




# ============================================================================
# Main Setup
# ============================================================================

# Development Mode
if [[ "$DEVENV" == "1" ]]; then
    echo "=== DEVELOPMENT MODE ==="
    SCRIPT_DIR="$(readlink -f "$(dirname "${BASH_SOURCE[0]}")/../lib/debian-nvidia-installer")"
else
    SCRIPT_DIR="/usr/lib/debian-nvidia-installer"
fi

# Ensure directories exist
mkdir -p "$(dirname "$LOG_FILE_PATH")" || {
    echo "Warning: Unable to create log directory: $(dirname "$LOG_FILE_PATH")" >&2
}

# Import modules
for file in "$SCRIPT_DIR"/translate/*.sh; do source "$file"; done
for file in "$SCRIPT_DIR"/*.sh; do source "$file"; done
for file in "$SCRIPT_DIR"/tui/*.sh; do source "$file"; done




# ============================================================================
# Enviroment Variables
# ============================================================================

# ----------------------------------------------------------------------------
# Variable: DEVENV
# Description:
#     Defines if the script should be executed in development mode.
#     This will replace paths to execute with source code structure.
# ----------------------------------------------------------------------------
: "${DEVENV:=0}"




# ============================================================================
# Global Variables
# ============================================================================

# ----------------------------------------------------------------------------
# Variable: SCRIPT_DIR
# Description:
#     Script root directory.
# ----------------------------------------------------------------------------
declare -g SCRIPT_DIR

# ----------------------------------------------------------------------------
# Variable: SCRIPT_VERSION
# Description:
#     Version of the script.
# ----------------------------------------------------------------------------
declare -g SCRIPT_VERSION="0.14.0"

# ----------------------------------------------------------------------------
# Variable: LOG_FILE_PATH
# Description:
#     Path to the log file.
# ----------------------------------------------------------------------------
declare -g LOG_FILE_PATH="/var/log/debian-nvidia-installer/debian-nvidia-installer.log"




# ============================================================================
# Functions
# ============================================================================

# ----------------------------------------------------------------------------
# Function: script::help
# Description:
#     Shows help tip.
# Params:
#     None
# ----------------------------------------------------------------------------
script::help() {
    local script_name
    script_name=$(basename "$0")
    cat <<EOF
$(tr::t_args "script::help.using" "$script_name")

$(tr::t "script::help.commands")
  --version, -v   $(tr::t "script::help.cmd.version")
  --help, -h      $(tr::t "script::help.cmd.help")

$(tr::t "script::help.examples")
  $script_name --version
  $script_name --help
EOF
}

tr::add "pt_BR" "script::help.using" "Uso: %1 [comando] [opções]"
tr::add "pt_BR" "script::help.commands" "Comandos:"
tr::add "pt_BR" "script::help.cmd.version" "Exibe a versão do script."
tr::add "pt_BR" "script::help.cmd.help" "Mostra esta ajuda."
tr::add "pt_BR" "script::help.examples" "Exemplos:"

tr::add "en_US" "script::help.using" "Usage: %1 [command] [options]"
tr::add "en_US" "script::help.commands" "Commands:"
tr::add "en_US" "script::help.cmd.version" "Displays the script version."
tr::add "en_US" "script::help.cmd.help" "Shows this help message."
tr::add "en_US" "script::help.examples" "Examples:"

tr::add "de_DE" "script::help.using" "Verwendung: %1 [Befehl] [Optionen]"
tr::add "de_DE" "script::help.commands" "Befehle:"
tr::add "de_DE" "script::help.cmd.version" "Zeigt die Skript-Version an."
tr::add "de_DE" "script::help.cmd.help" "Zeigt diese Hilfe an."
tr::add "de_DE" "script::help.examples" "Beispiele:"

# ----------------------------------------------------------------------------
# Function: script::exit
# Description:
#     Shows help tip.
# Params:
#     None
# ----------------------------------------------------------------------------
script::exit() {
    local exit_message
    local return_code

    exit_message="$(tr::t "default.script.exit")"
    return_code="${2:-0}"

    if [[ $return_code -gt 0 ]]; then
        log::critical "${1:-$exit_message}"
    else
        log::info "${1:-$exit_message}"
    fi

    echo "$(tr::t_args "script::exit.informlogpath" "$LOG_FILE_PATH")"
    log::input _ "$(tr::t "default.script.pause")"
    exit "$return_code"
}

tr::add "pt_BR" "script::exit.informlogpath" "O resumo da última execução do script está disponível em: %1"
tr::add "en_US" "script::exit.informlogpath" "The summary of the last script execution is available at: %1"
tr::add "de_DE" "script::exit.informlogpath" "Die Zusammenfassung der letzten Skript-Ausführung ist verfügbar unter: %1"

# ----------------------------------------------------------------------------
# Function: main::requirements
# Description:
#     Requirement checks.
# Params:
#     None
# ----------------------------------------------------------------------------
script::requirements() {
    # Ensure administrator permissions
    if ! utils::check_sudo; then
        log::warn "$(tr::t "default.script.rootaccess.required")"
        utils::force_sudo "$@" # Reexecuta o script
        script::exit "" 1
    fi

    # Check and installs dependencies
    log::info "$(tr::t "script::requirements.verifying")"
    if packages::install "dialog"; then
        log::info "$(tr::t "script::requirements.success")"
    else
        log::critical "$(tr::t "script::requirements.failure")"
        script::exit "" 1
    fi
}

tr::add "pt_BR" "script::requirements.invalid_distro" "SO não suportado: %1"
tr::add "pt_BR" "script::requirements.verifying" "Verificando dependências do script..."
tr::add "pt_BR" "script::requirements.success" "Dependências verificadas com sucesso."
tr::add "pt_BR" "script::requirements.failure" "Falha ao verificar dependências."

tr::add "en_US" "script::requirements.invalid_distro" "Unsupported OS: %1"
tr::add "en_US" "script::requirements.verifying" "Verifying script dependencies..."
tr::add "en_US" "script::requirements.success" "Dependencies verified successfully."
tr::add "en_US" "script::requirements.failure" "Failed to verify dependencies."

tr::add "de_DE" "script::requirements.invalid_distro" "Nicht unterstütztes Betriebssystem: %1"
tr::add "de_DE" "script::requirements.verifying" "Skript-Abhängigkeiten werden überprüft..."
tr::add "de_DE" "script::requirements.success" "Abhängigkeiten erfolgreich überprüft."
tr::add "de_DE" "script::requirements.failure" "Fehler beim Überprüfen der Abhängigkeiten."

# ----------------------------------------------------------------------------
# Function: main
# Description:
#     Main function.
# Params:
#     None
# ----------------------------------------------------------------------------
main() {
    # Language setup
    tr::detect_language

    # CLI arguments processing
    if [[ $# -gt 0 ]]; then
        case "$1" in
            --version|--VERSION|-v|-V)
                echo "$SCRIPT_VERSION"
                exit 0
                ;;
            --help|--HELP|-h|-H)
                script::help
                exit 0
                ;;
            *)
                echo "$(tr::t_args "default.invalid.command" "$*")"
                script::help
                exit 1
                ;;
        esac
    fi

    # Setup logger
    log::setup_logger "$LOG_FILE_PATH"

    # Show the wellcome message
    if [[ -f /etc/os-release ]]; then
        # shellcheck disable=SC1091
        source /etc/os-release
        log::info "$(tr::t_args "default.script.welcome" "$SCRIPT_VERSION" "$PRETTY_NAME")"
    else
        log::info "$(tr::t_args "default.script.welcome" "$SCRIPT_VERSION" "$(tr::t "default.script.distro.unknown")")"
    fi

    # Check and install requirements
    script::requirements "$@"

    # Start maio dialog
    tui::menu::main
    ret=$?

    # Clean and exit
    script::exit "" "$ret"
}

tr::add "pt_BR" "default.script.distro.unknown" "Distribuição não detectada"
tr::add "pt_BR" "default.invalid.command" "Comando inválido: %1"
tr::add "pt_BR" "default.script.welcome" "Debian NVIDIA Installer v%1\n
> Este instalador é distribuído sob a licença GPLv3.
> Repositório do projeto: https://github.com/devleonardoamaral/debian-nvidia-installer

Distribuição: %2\n
"

tr::add "en_US" "default.script.distro.unknown" "Unknown distribution"
tr::add "en_US" "default.invalid.command" "Invalid command: %1"
tr::add "en_US" "default.script.welcome" "Welcome to the Debian NVIDIA Installer %1\n
> This installer is released under the GPLv3 license.
> Project repository: https://github.com/devleonardoamaral/debian-nvidia-installer

Distribution: %2\n
"

tr::add "de_DE" "default.script.distro.unknown" "Unbekannte Distribution"
tr::add "de_DE" "default.invalid.command" "Ungültiger Befehl: %1"
tr::add "de_DE" "default.script.welcome" "Willkommen beim Debian NVIDIA Installer %1\n
> Dieser Installer wird unter der GPLv3-Lizenz veröffentlicht.
> Projekt-Repository: https://github.com/devleonardoamaral/debian-nvidia-installer

Distribution: %2\n
"

main
