#!/usr/bin/env bash
# list_active_connections
# -----------------------
# Muestra conexiones de red activas del sistema: puertos en escucha,
# conexiones establecidas y detección de IPs externas (no RFC1918).
#
# USO (directo):
#   list_active_connections [listening|established|external|all]
#
# Depende de: ss (iproute2)

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/../shell/bash_colors.sh"
source "$SCRIPT_DIR/../shell/bash_log.sh"
bash_colors
bash_log_init

# ─── Funciones puras ──────────────────────────────────────────────────────────

_conn_is_external_ip() {
    local ip="$1"
    # Devuelve 0 (verdadero) si no es loopback, link-local ni RFC1918
    [[ ! "$ip" =~ ^(127\.|::1|0\.0\.0\.0|10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.|fe80:) ]]
}

# ─── Funciones de efecto ──────────────────────────────────────────────────────

_conn_show_listening() {
    info "Puertos en escucha con proceso asociado..."
    echo ""
    echo -e "${PURPLE}════════════════════════════════════════════════════════════${NC}"
    ss -tlnp 2>/dev/null \
        | awk 'NR==1 {printf "%-6s %-25s %-25s %s\n", "Proto", "Local", "Peer", "Proceso"} NR>1 {printf "%-6s %-25s %-25s %s\n", $1, $4, $5, $7}' \
        | while IFS= read -r line; do echo -e "  ${DIM_GRAY}${line}${NC}"; done
    echo -e "${PURPLE}════════════════════════════════════════════════════════════${NC}"
}

_conn_show_established() {
    info "Conexiones establecidas..."
    echo ""
    echo -e "${PURPLE}════════════════════════════════════════════════════════════${NC}"
    ss -tnp state established 2>/dev/null \
        | awk 'NR==1 {printf "%-6s %-25s %-25s %s\n", "Proto", "Local", "Peer", "Proceso"} NR>1 {printf "%-6s %-25s %-25s %s\n", $1, $4, $5, $6}' \
        | while IFS= read -r line; do echo -e "  ${DIM_GRAY}${line}${NC}"; done
    echo -e "${PURPLE}════════════════════════════════════════════════════════════${NC}"
}

_conn_show_external() {
    info "Conexiones hacia IPs externas..."
    echo ""
    echo -e "${PURPLE}════════════════════════════════════════════════════════════${NC}"

    local found=0
    while IFS= read -r line; do
        local peer
        peer="$(echo "$line" | awk '{print $5}' | cut -d: -f1)"
        if _conn_is_external_ip "$peer"; then
            echo -e "  ${YELLOW}*${NC} $line"
            found=$((found + 1))
        fi
    done < <(ss -tnp state established 2>/dev/null | tail -n +2)

    echo -e "${PURPLE}════════════════════════════════════════════════════════════${NC}"
    echo ""
    if [[ $found -eq 0 ]]; then
        success "No se detectaron conexiones hacia IPs externas"
    else
        info "Total conexiones externas: $found"
    fi
}

# ─── Punto de entrada ─────────────────────────────────────────────────────────

list_active_connections() {
    local mode="${1:-all}"

    if ! command -v ss &>/dev/null; then
        error "list_active_connections: 'ss' no está disponible (sudo apt install iproute2)" >&2
        return 1
    fi

    case "$mode" in
        listening)
            _conn_show_listening
            ;;
        established)
            _conn_show_established
            ;;
        external)
            _conn_show_external
            ;;
        all)
            _conn_show_listening
            echo ""
            _conn_show_established
            echo ""
            _conn_show_external
            ;;
        *)
            error "list_active_connections: modo no válido '$mode'. Use: listening|established|external|all" >&2
            return 1
            ;;
    esac
}

# Ejecutar si se llama directamente
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    list_active_connections "$@"
fi
