import json
from datetime import datetime

# 1) Descripciones de cada sección para mostrar en la plantilla
SIMULADOR_DESCRIPCIONES = {
    "target": {
        "titulo": "Host auditado",
        "descripcion": "IP del servidor/host al que se aplicó el simulador de ataques."
    },
    "timestamp": {
        "titulo": "Marca temporal",
        "descripcion": "Fecha y hora en la que se inició la ejecución del simulador."
    },
    "tcp_abiertos": {
        "titulo": "Puertos TCP abiertos",
        "descripcion": "Lista de puertos TCP que respondieron con SYN-ACK. Se recomienda filtrar si no son necesarios."
    },
    "udp_abiertos": {
        "titulo": "Puertos UDP abiertos/filtrados",
        "descripcion": "Lista de puertos UDP que no devolvieron ICMP 'port unreachable'; pueden estar abiertos o filtrados."
    },
    "ftp_anonimo": {
        "titulo": "FTP con acceso anónimo",
        "descripcion": "Indica si el servicio FTP permite login anónimo (true/false). ENS Alto prohíbe FTP anónimo sin control."
    },
    "telnet_banner": {
        "titulo": "Banner Telnet",
        "descripcion": "Si hay servicio Telnet, se captura su banner. null indica que no hay Telnet en el host."
    },
    "icmp_enviados": {
        "titulo": "Paquetes ICMP enviados",
        "descripcion": "Cantidad de paquetes ICMP enviados (prueba de flood ligero). Un valor bajo (<10) suele ser aceptable para pruebas internas."
    }
}

def parsear_informe_simulador(filepath: str) -> dict:
    """
    Lee un fichero JSON (informe_simulador.json) con un único objeto.
    Devuelve un dict con las claves: target, timestamp, tcp_abiertos, udp_abiertos,
    ftp_anonimo, telnet_banner, icmp_enviados. 
    Además añade recomendaciones básicas por cada sección.
    """
    try:
        with open(filepath, 'r', encoding='utf-8') as f:
            datos = json.load(f)
    except Exception as e:
        raise RuntimeError(f"Error al leer o parsear JSON: {e}")

    informe = {}

    # Asegurarnos de que todas las claves estén presentes (si faltase alguna, la ponemos a None o lista vacía)
    informe["target"] = datos.get("target", "desconocido")
    informe["timestamp"] = datos.get("timestamp", "")
    informe["tcp_abiertos"] = datos.get("tcp_abiertos", [])
    informe["udp_abiertos"] = datos.get("udp_abiertos", [])
    informe["ftp_anonimo"] = datos.get("ftp_anonimo", False)
    informe["telnet_banner"] = datos.get("telnet_banner", None)
    informe["icmp_enviados"] = datos.get("icmp_enviados", 0)

    # 2) Generar recomendaciones automáticas para cada sección
    recomendaciones = {}

    # TCP abiertos
    if informe["tcp_abiertos"]:
        puertos = informe["tcp_abiertos"]
        lista_puertos = ", ".join(str(p) for p in puertos)
        recomendaciones["tcp_abiertos"] = (
            f"Se detectaron puertos TCP abiertos: [{lista_puertos}]. "
            "Si alguno no es necesario, bloquéalo en el firewall (iptables/UFW) o ciérralo en el servidor. "
            "En caso de servicio HTTP (80/443), verifica que esté correctamente protegido con TLS."
        )
    else:
        recomendaciones["tcp_abiertos"] = "No se detectaron puertos TCP abiertos en los escaneados."

    # UDP abiertos/filtrados
    if informe["udp_abiertos"]:
        puertos_udp = informe["udp_abiertos"]
        lista_udp = ", ".join(str(p) for p in puertos_udp)
        recomendaciones["udp_abiertos"] = (
            f"Puertos UDP abiertos/filtrados: [{lista_udp}]. "
            "Verifica si esos servicios (DNS, SNMP, etc.) deben estar expuestos. "
            "De lo contrario, añádelos a las reglas de bloqueo de UDP en el firewall."
        )
    else:
        recomendaciones["udp_abiertos"] = "No se detectaron puertos UDP abiertos o filtrados."

    # FTP anónimo
    if informe["ftp_anonimo"]:
        recomendaciones["ftp_anonimo"] = (
            "Se detectó que FTP permite login anónimo. ENS Alto (MP.SI.5) exige restringir acceso anónimo o deshabilitar FTP. "
            "Recomendación: deshabilitar FTP anónimo o configurar usuarios con credenciales seguras."
        )
    else:
        recomendaciones["ftp_anonimo"] = "No se detectó FTP con acceso anónimo (OK)."

    # Telnet
    if informe["telnet_banner"]:
        recomendaciones["telnet_banner"] = (
            f"Servicio Telnet detectado. Banner: '{informe['telnet_banner']}'. ENS Alto (MP.SI.4) prohíbe Telnet por inseguro. "
            "Recomendación: deshabilitar Telnet y usar SSH."
        )
    else:
        recomendaciones["telnet_banner"] = "No se detectó servicio Telnet (OK)."

    # ICMP enviados
    icmp_n = informe["icmp_enviados"]
    if icmp_n > 0:
        recomendaciones["icmp_enviados"] = (
            f"Se enviaron {icmp_n} paquetes ICMP como prueba (flood ligero). "
            "Si responden todos, la red permite ICMP; considera filtrar ICMP desde hosts no confiables."
        )
    else:
        recomendaciones["icmp_enviados"] = "No se ejecutó ICMP flood (OK)."

    # Attach descriptions y recomendaciones en una sola estructura
    resultado = {}
    for clave, meta in SIMULADOR_DESCRIPCIONES.items():
        resultado[clave] = {
            "dato": informe.get(clave),
            "titulo": meta["titulo"],
            "descripcion": meta["descripcion"],
            "recomendacion": recomendaciones.get(clave, "")
        }

    return resultado
