#!/usr/bin/bash
# +--------------------------------------------------------------------+
# EFA-NG Configure
# Version 20260827
# +--------------------------------------------------------------------+
# Copyright (C) 2026  https://efa-ng.space.ua
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
# +--------------------------------------------------------------------+

shopt -s extglob

# Load functions
. /var/eFa/lib/eFa-Configure/func_getipsettings
. /var/eFa/lib/eFa-Configure/func_apachesettings
. /var/eFa/lib/eFa-Configure/func_mailsettings
. /var/eFa/lib/eFa-Configure/func_systemrestore
. /var/eFa/lib/eFa-Configure/func_recovermariadb
. /var/eFa/lib/eFa-Configure/func_spamsettings
. /var/eFa/lib/eFa-Configure/func_virussettings
. /var/eFa/lib/eFa-Configure/func_askcleandeliver
. /var/eFa/lib/eFa-Configure/func_asknonspam
. /var/eFa/lib/eFa-Configure/func_askspam
. /var/eFa/lib/eFa-Configure/func_ipsettings
. /var/eFa/lib/eFa-Configure/func_greylisting
. /var/eFa/lib/eFa-Configure/func_tunables
. /var/eFa/lib/eFa-Configure/func_tunables_children
. /var/eFa/lib/eFa-Configure/func_tunables_procdb
. /var/eFa/lib/eFa-Configure/func_setipsettings
. /var/eFa/lib/eFa-Configure/func_askmaxsize
. /var/eFa/lib/eFa-Configure/func_mailwatchsettings
. /var/eFa/lib/eFa-Configure/func_resetadmin
. /var/eFa/lib/eFa-Configure/func_askmaxsizemailwatch
. /var/eFa/lib/eFa-Configure/func_askhighspammailwatch
. /var/eFa/lib/eFa-Configure/func_askmalwarepatrol
. /var/eFa/lib/eFa-Configure/func_retention
. /var/eFa/lib/eFa-Configure/func_maintenance
. /var/eFa/lib/eFa-Configure/func_peruser
. /var/eFa/lib/eFa-Configure/func_letsencrypt
. /var/eFa/lib/eFa-Configure/func_askdccservers
. /var/eFa/lib/eFa-Configure/func_dkim_dmarc
. /var/eFa/lib/eFa-Configure/func_webmin
. /var/eFa/lib/eFa-Configure/func_maxmind
. /var/eFa/lib/eFa-Configure/func_fail2ban
. /var/eFa/lib/eFa-Configure/func_backup
. /var/eFa/lib/eFa-Configure/func_asksigrules
. /var/eFa/lib/eFa-Configure/func_trustednetworks

# Configuration & UI mode
CONFIG_FILE="/etc/eFa/eFa-Configure.conf"
if [ -f "$CONFIG_FILE" ]; then
  . "$CONFIG_FILE"
fi
UI_MODE="${UI_MODE:-modern}"

# Colors
red='\E[00;31m'
green='\E[00;32m'
yellow='\E[00;33m'
blue='\E[00;34m'
magenta='\E[00;35m'
cyan='\E[00;36m'
bold='\E[1m'
dim='\E[2m'
clean='\E[00m'

# Get version
eFaVERSION="$(head -n 1 /etc/eFa-Version 2>/dev/null || echo '6.0.6')"

# Trap signals
trap '' SIGINT SIGQUIT SIGTSTP

# Helper functions
pause(){
  read -p "Press [Enter] key to continue..." fackEnterKey || exit 0
}

func_echo-header(){
  clear
  echo -e "--------------------------------------------------------------"
  echo -e "---       Welcome to the EFA-NG Configuration program      ---"
  echo -e "---                 https://efa-ng.space.ua                ---"
  echo -e "---          Support Channel: https://t.me/EFA_NG          ---"
  echo -e "--------------------------------------------------------------"
  echo ""
}

# Update Now function
func_update-now() {
  func_echo-header
  echo -e "$green[eFa-NG]$clean - System & Package Update"
  echo ""
  echo -e "Checking for available package updates..."
  echo ""
  dnf --refresh check-update
  local dnf_status=$?
  if [ $dnf_status -eq 0 ]; then
    echo ""
    echo -e "$green[eFa-NG]$clean All packages are up to date."
    echo ""
  elif [ $dnf_status -eq 100 ]; then
    echo ""
    echo -e "$yellow[eFa-NG]$clean Updates are available for this system.$clean"
    echo ""
    local yesno
    read -p "Do you want to apply updates now? (y/N): " yesno || yesno="n"
    if [[ $yesno =~ ^[Yy] ]]; then
      echo ""
      echo -e "$green[eFa-NG]$clean Updating system packages..."
      dnf -y update
      echo ""
      echo -e "$green[eFa-NG]$clean Reloading web and mail services..."
      systemctl reload php-fpm httpd 2>/dev/null || true
      systemctl reload postfix 2>/dev/null || true
      echo ""
      echo -e "$green[eFa-NG]$clean System update completed successfully!"
    else
      echo -e "$green[eFa-NG]$clean Update cancelled."
    fi
  else
    echo -e "$red[eFa-NG] An error occurred while checking for updates.$clean"
  fi
  pause
}

# Reboot function
func_reboot() {
  local rebootmenu=1
  while [ $rebootmenu -eq 1 ]; do
    func_echo-header
    echo -e "Are you sure you want to reboot this host?"
    echo -e ""
    echo -e "Y)  Yes I am sure"
    echo -e "N)  No take me back!"
    echo -e ""
    echo -e -n "$green[eFa-NG]$clean : "
    local choice
    read choice || return
    case $choice in
      Y|y) reboot && exit 0 ;;
      N|n) return ;;
      *) echo -e "Error \"$choice\" is not an option..." && sleep 1 ;;
    esac
  done
}

# Halt function
func_halt() {
  local haltmenu=1
  while [ $haltmenu -eq 1 ]; do
    func_echo-header
    echo -e "Are you sure you want to halt this host?"
    echo -e ""
    echo -e "Y)  Yes I am sure"
    echo -e "N)  No take me back!"
    echo -e ""
    echo -e -n "$green[eFa-NG]$clean : "
    local choice
    read choice || return
    case $choice in
      Y|y) shutdown -h now && exit 0 ;;
      N|n) return ;;
      *) echo -e "Error \"$choice\" is not an option..." && sleep 1 ;;
    esac
  done
}

# IP address helpers
function checkip4(){
  local ip=$1
  local stat=1
  if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
    OIFS=$IFS
    IFS='.'
    ip=($ip)
    IFS=$OIFS
    [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
    stat=$?
  fi
  return $stat
}

function checkip4cidr(){
  local ip=$1
  local stat=1
  if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}(\/[0-9]{1,2})?$ ]]; then
    OIFS=$IFS
    IFS='/'
    ipcidr=($ip)
    cidr=${ipcidr[1]}
    ip=${ipcidr[0]}
    IFS='.'
    ip=($ip)
    IFS=$OIFS
    [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 && ${ip[2]} -le 255 && ${ip[3]} -le 255 && $cidr -lt 33 ]]
    stat=$?
  fi
  return $stat
}

function checkip6(){
  local ip=$1
  if [[ $ip =~ ^([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])$ ]]; then
    return 0
  fi
  return 1
}

# Switch UI Mode function
func_switch_ui_mode() {
  func_echo-header
  echo -e "$cyan┌────────────────────────────────────────────────────────────┐$clean"
  echo -e "$cyan│                   SWITCH INTERFACE MODE                    │$clean"
  echo -e "$cyan└────────────────────────────────────────────────────────────┘$clean"
  echo ""
  echo -e " Current Mode: $green$UI_MODE$clean"
  echo ""
  echo -e " 1) Modern Dashboard  - Interactive visual layout with live status"
  echo -e " 2) Classic Menu      - Traditional 2-column numbered text menu"
  echo -e " 3) TUI Dialog        - Fullscreen curses dialogs (whiptail)"
  echo ""
  echo -e " c) Cancel"
  echo ""
  echo -e -n "$green[eFa-NG]$clean Choose interface mode [1-3, c]: "
  local mode_choice
  read mode_choice || return 0
  case $mode_choice in
    1) UI_MODE="modern" ;;
    2) UI_MODE="classic" ;;
    3) UI_MODE="tui" ;;
    *) return 0 ;;
  esac
  mkdir -p /etc/eFa
  echo "UI_MODE=\"$UI_MODE\"" > "$CONFIG_FILE"
  echo ""
  echo -e "$green[eFa-NG]$clean Interface mode switched to $green$UI_MODE$clean and saved."
  sleep 1
}

# Choice dispatcher
func_dispatch_choice() {
  local choice="$1"
  case $choice in
    0) clear; SSHTTY=`/usr/bin/tty |awk -F '/' '{print $3"/"$4}'`; SSHPID=`ps aux | egrep "sshd: [a-zA-Z]+@" | grep -w $SSHTTY | awk '{print $2}'`; kill $SSHPID ;;
    1) exit 0 ;;
    2) func_reboot ;;
    3) func_halt ;;
    4) func_ip-settings ;;
    5) func_tunables ;;
    6) func_mailwatch-settings ;;
    7) func_mail-settings ;;
    8) func_spam-settings ;;
    9) func_recover-mariadb ;;
    10) func_apache-settings ;;
    11) func_virus-settings ;;
    12) func_system-restore ;;
    13) func_update-now ;;
    14) func_maintenance-mode ;;
    15) func_lets-encrypt ;;
    16) func_dkim-dmarc ;;
    17) func_webmin ;;
    18) func_fail2ban ;;
    19) func_backup-settings ;;
    M|m) func_switch_ui_mode ;;
    T|t) UI_MODE="tui"; func_tui_menu ;;
    R|r) return 0 ;;
    *) echo -e "Error \"$choice\" is not an option..." && sleep 1 ;;
  esac
}

fmt_full_row() {
  local label="$1"
  local val="$2"
  local content="${label} : ${val}"
  if [ ${#content} -gt 68 ]; then
    content="${content:0:65}..."
  fi
  printf " ${cyan}│${clean}  %-68.68s  ${cyan}│${clean}\n" "$content"
}

fmt_split_row() {
  local l_label="$1"
  local l_val="$2"
  local r_label="$3"
  local r_val="$4"
  
  local left="${l_label} : ${l_val}"
  if [ ${#left} -gt 41 ]; then
    left="${left:0:38}..."
  fi
  local right="${r_label} : ${r_val}"
  if [ ${#right} -gt 26 ]; then
    right="${right:0:23}..."
  fi
  printf " ${cyan}│${clean}  %-42.42s%-26.26s  ${cyan}│${clean}\n" "$left" "$right"
}

# Modern Dashboard Menu
show_modern_menu() {
  local host=$(hostname -f 2>/dev/null || hostname)
  local ip=$(hostname -I 2>/dev/null | awk '{print $1}')
  local uptime_str=$(uptime -p 2>/dev/null | sed 's/^up //' || echo "unknown")
  local load=$(awk '{print $1", "$2", "$3}' /proc/loadavg 2>/dev/null)
  local mem=$(free -m 2>/dev/null | awk '/Mem:/ {printf "%.1fG / %.1fG", $3/1024, $2/1024}')

  local b_ok="${green}● OK ${clean}"
  local b_off="${red}○ OFF${clean}"
  local b_on="${green}● ON ${clean}"

  local b_postfix=$b_off
  [[ $(systemctl is-active postfix 2>/dev/null) == "active" ]] && b_postfix=$b_ok

  local b_ms=$b_off
  [[ $(systemctl is-active mailscanner 2>/dev/null) == "active" ]] && b_ms=$b_ok

  local b_maria=$b_off
  [[ $(systemctl is-active mariadb 2>/dev/null) == "active" ]] && b_maria=$b_ok

  local b_phpfpm=$b_off
  [[ $(systemctl is-active php-fpm 2>/dev/null) == "active" ]] && b_phpfpm=$b_ok

  local b_httpd=$b_off
  [[ $(systemctl is-active httpd 2>/dev/null) == "active" ]] && b_httpd=$b_ok

  local b_f2b=$b_off
  [[ $(systemctl is-active fail2ban 2>/dev/null) == "active" ]] && b_f2b=$b_ok

  local b_maint="${green}○ OFF${clean}"
  [[ ! -f /etc/cron.d/eFa-Monitor.cron ]] && b_maint="${yellow}⚠ ON ${clean}"

  local b_bk="${green}● ON ${clean}"
  [[ -f /etc/eFa/eFa-Backup.disabled ]] && b_bk="${yellow}○ OFF${clean}"

  local b_upd=$b_ok

  clear
  echo -e " ${cyan}┌────────────────────────────────────────────────────────────────────────┐${clean}"
  echo -e " ${cyan}│${clean}                      ${bold}EFA-NG CONFIGURATION CONSOLE${clean}                      ${cyan}│${clean}"
  echo -e " ${cyan}│${clean}              https://efa-ng.space.ua  |  https://t.me/EFA_NG            ${cyan}│${clean}"
  echo -e " ${cyan}├────────────────────────────────────────────────────────────────────────┤${clean}"
  fmt_full_row  "Hostname" "$host"
  fmt_full_row  "IP Addr " "$ip"
  fmt_split_row "Uptime  " "$uptime_str" "Load   " "$load"
  fmt_split_row "Memory  " "$mem" "Version" "$eFaVERSION (eFa-NG)"
  echo -e " ${cyan}├────────────────────────────────────────────────────────────────────────┤${clean}"
  echo -e " ${cyan}│${clean}   ${bold}SERVICES:${clean}                                                            ${cyan}│${clean}"
  echo -e " ${cyan}│${clean}   Postfix: [$b_postfix]       MailScanner: [$b_ms]       MariaDB: [$b_maria]   ${cyan}│${clean}"
  echo -e " ${cyan}│${clean}   Apache : [$b_httpd]       Fail2Ban   : [$b_f2b]       PHP-FPM: [$b_phpfpm]   ${cyan}│${clean}"
  echo -e " ${cyan}│${clean}   Backup : [$b_bk]       Maintenance: [$b_maint]       Updates: [$b_upd]   ${cyan}│${clean}"
  echo -e " ${cyan}└────────────────────────────────────────────────────────────────────────┘${clean}"
  echo ""
  echo -e " ${bold}┌─ SYSTEM & NETWORK ───────────────┐  ┌─ MAIL & FILTERING ───────────────┐${clean}"
  echo -e " ${bold}│${clean}  1) Shell Access (Bash)          ${bold}│  │${clean}  6) MailWatch Settings           ${bold}│${clean}"
  echo -e " ${bold}│${clean}  2) Reboot System                ${bold}│  │${clean}  7) Mail Settings (Domains/Relay)${bold}│${clean}"
  echo -e " ${bold}│${clean}  3) Halt / Power Off             ${bold}│  │${clean}  8) Spam Filter Settings         ${bold}│${clean}"
  echo -e " ${bold}│${clean}  4) IP & DNS Settings            ${bold}│  │${clean} 11) Virus & Clean Delivery       ${bold}│${clean}"
  echo -e " ${bold}│${clean}  5) System Tunables              ${bold}│  │${clean} 16) DKIM and DMARC Wizard        ${bold}│${clean}"
  echo -e " ${bold}└──────────────────────────────────┘  └──────────────────────────────────┘${clean}"
  echo -e " ${bold}┌─ SECURITY & ACCESS ──────────────┐  ┌─ MAINTENANCE & TOOLS ────────────┐${clean}"
  echo -e " ${bold}│${clean} 10) Apache & HTTPS Settings      ${bold}│  │${clean}  9) MariaDB Database Recovery    ${bold}│${clean}"
  echo -e " ${bold}│${clean} 15) Let's Encrypt SSL Certs      ${bold}│  │${clean} 12) Backup & Server Migration   ${bold}│${clean}"
  echo -e " ${bold}│${clean} 17) Webmin Control Panel         ${bold}│  │${clean} 13) Update System & Packages     ${bold}│${clean}"
  echo -e " ${bold}│${clean} 18) Fail2Ban Protection          ${bold}│  │${clean} 14) Maintenance Mode (Toggle)    ${bold}│${clean}"
  echo -e " ${bold}│${clean}                                  ${bold}│  │${clean} 19) Auto-Backup Settings         ${bold}│${clean}"
  echo -e " ${bold}└──────────────────────────────────┘  └──────────────────────────────────┘${clean}"
  echo ""
  echo -e "   ${bold}0)${clean} Logout (SSH)      ${bold}M)${clean} Switch UI Mode (Classic/TUI)      ${bold}R)${clean} Refresh"
  echo ""
  echo -e -n " ${green}[eFa-NG]${clean} : "
  local choice
  read choice || exit 0
  func_dispatch_choice "$choice"
}

# Classic Menu
show_classic_menu() {
  func_echo-header
  echo -e "You are currently running $eFaVERSION."
  echo ""
  echo -e "Please choose an option:"
  echo -e " "
  echo -e "0) Logout from ssh                    10) Apache Settings"
  echo -e "1) Shell                              11) Virus Settings"
  echo -e "2) Reboot system                      12) Backup & Server Migration"
  echo -e "3) Halt system                        13) Update Now"
  echo -e "4) IP Settings                        14) Maintenance Mode"
  echo -e "5) Tunables                           15) Let's Encrypt"
  echo -e "6) MailWatch Settings                 16) DKIM and DMARC"
  echo -e "7) Mail Settings                      17) Webmin"
  echo -e "8) Spam Settings                      18) Fail2Ban"
  echo -e "9) MariaDB Recovery                   19) Auto-Backup settings"
  echo -e ""
  echo -e "M) Switch to Modern Mode              T) Open TUI Dialog"
  echo -e ""
  echo -e -n "$green[eFa-NG]$clean : "
  local choice
  read choice || exit 0
  func_dispatch_choice "$choice"
}

# TUI (Whiptail) Menu
func_tui_menu() {
  if ! command -v whiptail >/dev/null 2>&1; then
    echo -e "$red[ERROR]$clean whiptail is not installed. Falling back to Modern CLI."
    UI_MODE="modern"
    sleep 1
    return 0
  fi

  while true; do
    CHOICE=$(whiptail --title "EFA-NG Configuration Console" \
      --backtitle "EFA-NG Project (https://efa-ng.space.ua | Support: https://t.me/EFA_NG)" \
      --menu "Select an option using arrow keys and press Enter:" 24 76 16 \
      "1"  "Shell (Exit to Bash)" \
      "2"  "Reboot System" \
      "3"  "Halt System" \
      "4"  "IP & DNS Settings" \
      "5"  "System Tunables (Threads)" \
      "6"  "MailWatch Settings" \
      "7"  "Mail Settings (Relay/Domains)" \
      "8"  "Spam Filter Settings" \
      "9"  "MariaDB Database Recovery" \
      "10" "Apache & HTTPS Settings" \
      "11" "Virus & Clean Delivery Settings" \
      "12" "Backup & Server Migration Wizard" \
      "13" "Update System & Packages" \
      "14" "Maintenance Mode Toggle" \
      "15" "Let's Encrypt SSL Certificates" \
      "16" "DKIM and DMARC Wizard" \
      "17" "Webmin Control Panel" \
      "18" "Fail2Ban Protection" \
      "19" "Auto-Backup Settings" \
      "M"  "Switch UI Mode (Classic / Modern / TUI)" \
      "0"  "Logout from SSH" \
      3>&1 1>&2 2>&3)
    
    local ret=$?
    if [ $ret -ne 0 ]; then
      # User pressed Cancel or Esc
      clear
      echo -e "$green[eFa-NG]$clean Exited TUI."
      exit 0
    fi
    
    func_dispatch_choice "$CHOICE"
    
    # If mode was switched away from TUI, exit loop so main dispatcher takes over
    if [ "$UI_MODE" != "tui" ]; then
      break
    fi
  done
}

# Main entry point
if [ `whoami` == root ]; then
  while true; do
    if [ "$UI_MODE" == "tui" ]; then
      func_tui_menu
      exit 0
    elif [ "$UI_MODE" == "classic" ]; then
      show_classic_menu
    else
      show_modern_menu
    fi
  done
else
  echo -e "$red [eFa-NG] ERROR: Please become root.$clean"
  exit 0
fi
