#!/usr/bin/env bash
# analyze_dns
# -----------
# Análisis DNS completo de un dominio: registros A/AAAA/MX/NS/TXT/CNAME/SOA,
# consulta whois y verificación contra listas negras DNSBL.
#
# USO (directo):
#   analyze_dns example.com [records|whois|dnsbl|all]
#
# Depende de: dig, whois (opcional), curl (para DNSBL)

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 ──────────────────────────────────────────────────────────

_dns_is_valid_domain() {
    local domain="$1"
    [[ -n "$domain" && "$domain" =~ ^[a-zA-Z0-9._-]+\.[a-zA-Z]{2,}$ ]]
}

_dns_build_dnsbl_query() {
    local ip="$1"
    local bl="$2"
    local reversed
    reversed="$(echo "$ip" | awk -F. '{print $4"."$3"."$2"."$1}')"
    echo "${reversed}.${bl}"
}

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

_dns_query_record() {
    local domain="$1"
    local type="$2"
    local result
    result="$(dig +short "$type" "$domain" 2>/dev/null || true)"
    if [[ -z "$result" ]]; then
        echo "  (sin registros)"
    else
        echo "$result" | while IFS= read -r line; do
            echo "  * $line"
        done
    fi
}

_dns_show_all_records() {
    local domain="$1"
    echo ""
    for type in A AAAA MX NS TXT CNAME SOA; do
        echo -e "${CYAN}── ${type} ──────────────────${NC}"
        _dns_query_record "$domain" "$type"
        echo ""
    done
}

_dns_show_whois() {
    local domain="$1"
    echo ""
    info "Consultando whois de ${domain}..."
    echo -e "${PURPLE}════════════════════════════════════════════════════════════${NC}"
    whois "$domain" 2>/dev/null \
        | grep -iE "(registrar|registrant|creation|expiry|expire|updated|name server|status)" \
        | head -20 \
        | while IFS= read -r line; do echo -e "  ${DIM_GRAY}${line}${NC}"; done
    echo -e "${PURPLE}════════════════════════════════════════════════════════════${NC}"
}

_dns_check_dnsbl() {
    local domain="$1"
    local ip
    ip="$(dig +short A "$domain" 2>/dev/null | head -1 || true)"

    if [[ -z "$ip" ]]; then
        warning "No se pudo resolver la IP de $domain para comprobar DNSBL"
        return
    fi

    info "IP a comprobar: $ip"
    echo ""

    local blacklists=(
        "zen.spamhaus.org"
        "bl.spamcop.net"
        "dnsbl.sorbs.net"
        "b.barracudacentral.org"
    )

    local found=0
    for bl in "${blacklists[@]}"; do
        local query
        query="$(_dns_build_dnsbl_query "$ip" "$bl")"
        local result
        result="$(dig +short A "$query" 2>/dev/null || true)"
        if [[ -n "$result" ]]; then
            echo -e "  ${RED}LISTADO${NC} ${bl} ($result)"
            found=$((found + 1))
        else
            echo -e "  ${GREEN}limpio${NC}  ${bl}"
        fi
    done

    echo ""
    if [[ $found -eq 0 ]]; then
        success "La IP no aparece en ninguna lista negra comprobada"
    else
        warning "La IP aparece en ${found} lista(s) negra(s)"
    fi
}

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

analyze_dns() {
    local domain="$1"
    local mode="${2:-all}"

    if [[ -z "$domain" ]]; then
        error "analyze_dns: se requiere un dominio como primer argumento" >&2
        return 1
    fi

    if ! _dns_is_valid_domain "$domain"; then
        error "analyze_dns: dominio no válido: '$domain'" >&2
        return 1
    fi

    if ! command -v dig &>/dev/null; then
        error "analyze_dns: 'dig' no está instalado (sudo apt install dnsutils)" >&2
        return 1
    fi

    info "Analizando: ${domain}"

    case "$mode" in
        records)
            _dns_show_all_records "$domain"
            ;;
        whois)
            if ! command -v whois &>/dev/null; then
                error "analyze_dns: 'whois' no está instalado (sudo apt install whois)" >&2
                return 1
            fi
            _dns_show_whois "$domain"
            ;;
        dnsbl)
            _dns_check_dnsbl "$domain"
            ;;
        all)
            _dns_show_all_records "$domain"
            if command -v whois &>/dev/null; then
                _dns_show_whois "$domain"
            else
                warning "whois no disponible, omitiendo"
            fi
            echo ""
            _dns_check_dnsbl "$domain"
            ;;
        *)
            error "analyze_dns: modo no válido '$mode'. Use: records|whois|dnsbl|all" >&2
            return 1
            ;;
    esac
}

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