#!/bin/bash
#
# Script de configurare interactivă avansată pentru UnderChat IRCd
# Limba: Română
#

set -e

# Culori
ROSU='\033[0;31m'
VERDE='\033[0;32m'
GALBEN='\033[1;33m'
ALBASTRU='\033[0;34m'
MOV='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m'

# Variabile
PREFIX="${PREFIX:-$HOME/ircd}"
CONFIG_FILE="${1:-$PREFIX/etc/ircd.conf}"

# Funcții auxiliare
log_title() {
    echo ""
    echo -e "${MOVE}╔════════════════════════════════════════╗${NC}"
    echo -e "${MOVE}║  $1${NC}"
    echo -e "${MOVE}╚════════════════════════════════════════╝${NC}"
}

log_section() {
    echo ""
    echo -e "${CYAN}>>> $1${NC}"
}

log_ok() {
    echo -e "${VERDE}✓ $1${NC}"
}

log_err() {
    echo -e "${ROSU}✗ $1${NC}"
}

log_info() {
    echo -e "${ALBASTRU}ℹ $1${NC}"
}

# Validare input
validate_hostname() {
    if [[ $1 =~ ^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$ ]]; then
        return 0
    else
        return 1
    fi
}

validate_numeric() {
    if [[ $1 =~ ^[0-9]+$ ]] && [ "$1" -ge 0 ] && [ "$1" -le 4095 ]; then
        return 0
    else
        return 1
    fi
}

validate_port() {
    if [[ $1 =~ ^[0-9]+$ ]] && [ "$1" -ge 1024 ] && [ "$1" -le 65535 ]; then
        return 0
    else
        return 1
    fi
}

validate_email() {
    if [[ $1 =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
        return 0
    else
        return 1
    fi
}

# Meniu interactiv
read_input() {
    local prompt="$1"
    local default="$2"
    local input

    if [ -n "$default" ]; then
        echo -n -e "${GALBEN}${prompt}${NC} [${default}]: "
    else
        echo -n -e "${GALBEN}${prompt}${NC}: "
    fi

    read -r input

    if [ -z "$input" ]; then
        echo "$default"
    else
        echo "$input"
    fi
}

# Etapa 1: Configurare generală
configure_general() {
    log_title "CONFIGURARE GENERALĂ"

    log_section "Setări de bază ale serverului"

    # Domeniu rețea
    NETWORK=$(read_input "Domeniu/Rețea (ex: underchat.org)" "underchat.org")
    log_ok "Domeniu rețea: $NETWORK"

    # Nume server
    while true; do
        SERVER_NAME=$(read_input "Nume server (ex: ns1.${NETWORK})" "ns1.${NETWORK}")
        if validate_hostname "$SERVER_NAME"; then
            log_ok "Nume server valid: $SERVER_NAME"
            break
        else
            log_err "Nume server invalid! Folosește format FQDN (ex: ns1.example.com)"
        fi
    done

    # Descriere
    SERVER_DESC=$(read_input "Descriere server" "The ${NETWORK} Network")
    log_ok "Descriere: $SERVER_DESC"

    # Virtual host (IP local)
    VHOST=$(read_input "Virtual Host / IP local" "127.0.0.1")
    log_ok "Virtual Host: $VHOST"

    # Numeric
    while true; do
        NUMERIC=$(read_input "Numeric server (0-4095)" "1")
        if validate_numeric "$NUMERIC"; then
            log_ok "Numeric valid: $NUMERIC"
            break
        else
            log_err "Numeric invalid! Folosește un număr între 0-4095"
        fi
    done
}

# Etapa 2: Informații administrator
configure_admin() {
    log_title "INFORMAȚII ADMINISTRATOR"

    ADMIN_LOCATION=$(read_input "Locație" "Romania")
    log_ok "Locație: $ADMIN_LOCATION"

    while true; do
        ADMIN_EMAIL=$(read_input "Email administrator" "admin@underchat.ro")
        if validate_email "$ADMIN_EMAIL"; then
            log_ok "Email: $ADMIN_EMAIL"
            break
        else
            log_err "Email invalid! Utilizează format corect (ex: admin@example.com)"
        fi
    done

    ADMIN_INFO=$(read_input "Informații contact suplimentare" "Contact: admin")
    log_ok "Info contact: $ADMIN_INFO"
}

# Etapa 3: Porturi
configure_ports() {
    log_title "CONFIGURARE PORTURI"

    log_section "Porturi pentru clienți"

    while true; do
        PORT1=$(read_input "Port standard (1024-65535)" "6667")
        if validate_port "$PORT1"; then
            log_ok "Port standard: $PORT1"
            break
        else
            log_err "Port invalid!"
        fi
    done

    while true; do
        PORT2=$(read_input "Port SSL/TLS (1024-65535)" "6697")
        if validate_port "$PORT2"; then
            [ "$PORT2" != "$PORT1" ] && log_ok "Port SSL: $PORT2" || log_err "Portul SSL trebuie să fie diferit de portul standard"
            [ "$PORT2" != "$PORT1" ] && break
        else
            log_err "Port invalid!"
        fi
    done

    log_section "Porturi pentru servere"

    while true; do
        SERVER_PORT=$(read_input "Port server-to-server" "6666")
        if validate_port "$SERVER_PORT"; then
            log_ok "Port server: $SERVER_PORT"
            break
        else
            log_err "Port invalid!"
        fi
    done
}

# Etapa 4: Clase de conexiuni
configure_classes() {
    log_title "CONFIGURARE CLASE DE CONEXIUNI"

    log_section "Setări pentru clienți"

    MAXLINKS=$(read_input "Maxim linkuri per client" "10")
    SENDQ=$(read_input "Dimensiune sendq (bytes)" "40000")
    PINGFREQ=$(read_input "Frecvență ping (secunde)" "120")

    log_ok "Configurare clase complete"
}

# Etapa 5: Operatori
configure_operators() {
    log_title "CONFIGURARE OPERATORI"

    log_section "Configurare Operator Principal"

    OPER_NAME=$(read_input "Nume operator" "AdminRoot")
    log_ok "Nume: $OPER_NAME"

    log_info "Pentru a genera parola, rulează:"
    echo -e "${CYAN}  $PREFIX/bin/umkpasswd${NC}"

    OPER_PASS=$(read_input "Hash parola operator (SMD5/bcrypt)" "")

    if [ -z "$OPER_PASS" ]; then
        log_err "Parola necesară! Generează cu umkpasswd"
        OPER_PASS='$2a$04$NTy1i.X/8pXekNBNbMRlOu1JAjIiMfPGIe1sZf0Xqq.2jzqPMfN/G'
        log_info "Se folosește parola implicită pentru testing"
    fi

    OPER_HOST=$(read_input "Host permis pentru operator" "*@*")
    log_ok "Host: $OPER_HOST"

    # Oper options
    read -p "Is this an admin operator? (y/n) [y]: " -n 1 IS_ADMIN
    IS_ADMIN=${IS_ADMIN:-y}
    echo ""
}

# Etapa 6: Setări avansate
configure_advanced() {
    log_title "SETĂRI AVANSATE"

    log_section "Caracteristici"

    read -p "Activezi autentificarea? (y/n) [y]: " -n 1 AUTH_ENABLED
    AUTH_ENABLED=${AUTH_ENABLED:-y}
    echo ""
    [ "$AUTH_ENABLED" = "y" ] && log_ok "Autentificare: Activată" || log_ok "Autentificare: Dezactivată"

    read -p "Activezi channelurile persistente? (y/n) [n]: " -n 1 PERSIST_CHANS
    PERSIST_CHANS=${PERSIST_CHANS:-n}
    echo ""
    [ "$PERSIST_CHANS" = "y" ] && log_ok "Canale persistente: Activate" || log_ok "Canale persistente: Dezactivate"

    read -p "Activezi SWHOIS? (y/n) [y]: " -n 1 SWHOIS_ENABLED
    SWHOIS_ENABLED=${SWHOIS_ENABLED:-y}
    echo ""
    [ "$SWHOIS_ENABLED" = "y" ] && log_ok "SWHOIS: Activat" || log_ok "SWHOIS: Dezactivat"

    IDLETIME=$(read_input "Timp maxim inactivitate (0=ilimitat)" "0")
    log_ok "Timp inactivitate: ${IDLETIME}s"
}

# Generare fișier de configurare
generate_config_file() {
    log_title "GENERARE FIȘIER CONFIGURARE"

    mkdir -p "$(dirname "$CONFIG_FILE")"

    # Conversie booleene
    AUTH_FEATURE=$([ "$AUTH_ENABLED" = "y" ] && echo "yes" || echo "no")
    PERSIST_FEATURE=$([ "$PERSIST_CHANS" = "y" ] && echo "yes" || echo "no")
    SWHOIS_FEATURE=$([ "$SWHOIS_ENABLED" = "y" ] && echo "yes" || echo "no")
    IS_ADMIN_OPER=$([ "$IS_ADMIN" = "y" ] && echo "yes" || echo "no")

    cat > "$CONFIG_FILE" << EOFCONFIG
# ============================================================================
# Fișier de configurare UnderChat IRCd
# Generat automat la: $(date)
# Script: configure-interactive.sh
# Model: Professional IRC Server
# ============================================================================

# ============================================================================
# SECȚIUNE: GENERAL
# ============================================================================
General {
    name = "$SERVER_NAME";
    vhost = "127.0.0.1";
    description = "$SERVER_DESC";
    numeric = $NUMERIC;
    dns server = "8.8.8.8";
    dns server = "1.1.1.1";
};

# ============================================================================
# SECȚIUNE: ADMIN
# ============================================================================
Admin {
    Location = "The $SERVER_NAME World";
    Location = "$ADMIN_LOCATION";
    Contact = "$ADMIN_EMAIL";
    Contact = "$ADMIN_INFO";
};

# ============================================================================
# SECȚIUNE: CLASE DE CONEXIUNI
# ============================================================================

Class {
    name = "Server";
    pingfreq = 1 minutes 30 seconds;
    connectfreq = 5 minutes;
    maxlinks = 1;
    sendq = 9000000;
};

Class {
    name = "Local";
    pingfreq = $PINGFREQ seconds;
    sendq = $SENDQ;
    maxlinks = $MAXLINKS;
    usermode = "+iw";
};

Class {
    name = "Other";
    pingfreq = $PINGFREQ seconds;
    sendq = $SENDQ;
    maxlinks = $MAXLINKS;
    usermode = "+ix";
};

Class {
    name = "Opers";
    pingfreq = $PINGFREQ seconds;
    sendq = $SENDQ;
    maxlinks = 20;
    local = no;
    freeform = yes;
    mode_lchan = yes;
    deop_lchan = yes;
    walk_lchan = yes;
    show_invis = yes;
    see_chan = yes;
    list_chan = yes;
    usermode = "+W";
    remove = yes;
};

# ============================================================================
# SECȚIUNE: CLIENT
# ============================================================================
Client {
    host = "*@*";
    ip = "*@*";
    class = "Other";
    maxlinks = $MAXLINKS;
};

# ============================================================================
# SECȚIUNE: PORTURI
# ============================================================================

# Port server-to-server
Port {
    vhost = "127.0.0.1" $SERVER_PORT;
    server = yes;
    hidden = yes;
};

# Port standard pentru clienți
Port {
    vhost = "127.0.0.1" $PORT1;
    hidden = yes;
};

# Port SSL/TLS pentru clienți
Port {
    vhost = "127.0.0.1" $PORT2;
    ssl = yes;
    hidden = yes;
};

# ============================================================================
# SECȚIUNE: OPERATORI
# ============================================================================

Operator {
    name = "$OPER_NAME";
    password = "$OPER_PASS";
    host = "$OPER_HOST";
    class = "Opers";
    admin = $IS_ADMIN_OPER;
    hide_oper = no;
    hide_channels = no;
};

# ============================================================================
# SECȚIUNE: JUPE - Nick-uri rezervate
# ============================================================================

Jupe {
    nick = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
    nick = "StatServ,NoteServ";
    nick = "ChanServ,ChanSaver";
    nick = "NickServ,NickSaver";
};

# ============================================================================
# SECȚIUNE: FEATURE - Caracteristici
# ============================================================================

features {
    "NETWORK" = "UnderchatNetwork";
    "DOMAINNAME" = "$SERVER_NAME";

    "LOG" = "SYSTEM" "FILE" "$PREFIX/log/ircd.log";
    "LOG" = "SYSTEM" "LEVEL" "CRIT";

    "HUB" = "TRUE";
    "RELIABLE_CLOCK" = "FALSE";
    "WALLOPS_OPER_ONLY" = "TRUE";
    "NODNS" = "FALSE";

    "CLIENT_FLOOD" = "1024";
    "BUFFERPOOL" = "27000000";

    "HOST_HIDING" = "TRUE";
    "HIDDEN_HOST" = "users.underchat.org";
    "HIDDEN_IP" = "127.0.0.1";

    "MAXCHANNELSPERUSER" = "60";
    "CHANNELLEN" = "200";
    "MAXBANS" = "50";

    "NICKLEN" = "12";
    "NICKNAMEHISTORYLENGTH" = "800";

    "HANGONGOODLINK" = "300";
    "HANGONRETRYDELAY" = "10";
    "CONNECTTIMEOUT" = "90";
    "PINGFREQUENCY" = "$PINGFREQ";
    "CONNECTFREQUENCY" = "600";

    "MPATH" = "$PREFIX/etc/ircd.motd";
    "PPATH" = "$PREFIX/var/ircd.pid";

    "HIS_SERVERNAME" = "*.underchat.org";
    "HIS_SERVERINFO" = "The UnderchatNetwork World";

    "CHECK" = "TRUE";
    "SETHOST" = "TRUE";
    "NETWORK_REHASH" = "TRUE";

    "HALFOPS" = "TRUE";
};

EOFCONFIG

    log_ok "Fișier de configurare generat: $CONFIG_FILE"
}

# Rezumat final
show_summary() {
    log_title "REZUMAT CONFIGURARE"

    echo -e "${CYAN}Setări general:${NC}"
    echo "  • Nume: $SERVER_NAME"
    echo "  • Descriere: $SERVER_DESC"
    echo "  • Numeric: $NUMERIC"
    echo ""

    echo -e "${CYAN}Administrator:${NC}"
    echo "  • Locație: $ADMIN_LOCATION"
    echo "  • Email: $ADMIN_EMAIL"
    echo ""

    echo -e "${CYAN}Porturi:${NC}"
    echo "  • Standard: $PORT1"
    echo "  • SSL/TLS: $PORT2"
    echo "  • Server: $SERVER_PORT"
    echo ""

    echo -e "${CYAN}Operator:${NC}"
    echo "  • Nick: $OPER_NICK"
    echo "  • Host: $OPER_HOST"
    echo ""

    echo -e "${VERDE}Configurare salvată în: $CONFIG_FILE${NC}"
    echo ""
}

# Funcție principală
main() {
    clear

    echo -e "${MOVE}"
    echo "╔════════════════════════════════════════╗"
    echo "║   Configurator UnderChat IRCd         ║"
    echo "║   Limba: Română                        ║"
    echo "║   Versiune: 1.0                        ║"
    echo "╚════════════════════════════════════════╝"
    echo -e "${NC}"

    # Executare pași
    configure_general
    configure_admin
    configure_ports
    configure_classes
    configure_operators
    configure_advanced

    # Generare și rezumat
    generate_config_file
    show_summary

    echo -e "${VERDE}✓ Configurare completă!${NC}"
    echo ""
    echo -e "${GALBEN}Pași următori:${NC}"
    echo "  1. Verifică configurarea: cat $CONFIG_FILE"
    echo "  2. Editează după necesitate: nano $CONFIG_FILE"
    echo "  3. Pornește serverul: $PREFIX/bin/ircd -f $CONFIG_FILE"
    echo ""
}

# Apelează funcția principală
main

