import os
from collections import Counter
from scapy.all import rdpcap, IP, IPv6, TCP, UDP, DNS, Raw

from pcapx.core.flows import extract_flows
from pcapx.core.http import extract_http_requests
from pcapx.core.tls import extract_tls_sni
from pcapx.core.dns import extract_dns_records
from pcapx.core.ports import extract_ports_and_services
from pcapx.core.timeline import extract_timeline
from pcapx.core.icmp import extract_icmp_activity
from pcapx.core.arp import extract_arp_activity
from pcapx.core.auth import extract_auth_evidence


def analyze_pcap(pcap_file: str) -> dict:
    if not os.path.exists(pcap_file):
        raise FileNotFoundError(pcap_file)

    packets = rdpcap(pcap_file)

    protocols = Counter()
    timestamps = []
    ips = set()

    # ================= Packet-level scan =================
    for pkt in packets:
        if hasattr(pkt, "time"):
            timestamps.append(float(pkt.time))

        if pkt.haslayer(IP):
            ips.add(pkt[IP].src)
            ips.add(pkt[IP].dst)

        if pkt.haslayer(IPv6):
            ips.add(pkt[IPv6].src)
            ips.add(pkt[IPv6].dst)
            protocols["IPv6"] += 1

        if pkt.haslayer(TCP):
            protocols["TCP"] += 1
        elif pkt.haslayer(UDP):
            protocols["UDP"] += 1

        if pkt.haslayer(DNS):
            protocols["DNS"] += 1

        # Raw but not TCP/UDP payloads (ARP, ICMP, etc.)
        if pkt.haslayer(Raw) and not pkt.haslayer(TCP) and not pkt.haslayer(UDP):
            protocols["Raw"] += 1

    duration = (
        round(max(timestamps) - min(timestamps), 2)
        if len(timestamps) > 1
        else 0
    )

    # ================= Evidence extractors =================
    flows = extract_flows(packets)
    ports_info = extract_ports_and_services(packets)

    dns = extract_dns_records(packets)
    raw_http = extract_http_requests(packets)
    tls = extract_tls_sni(packets)
    timeline = extract_timeline(packets)

    icmp = extract_icmp_activity(packets)
    arp = extract_arp_activity(packets)

    # ================= AUTH EVIDENCE =================
    auth = extract_auth_evidence(packets)

    # ================= HTTP NORMALIZATION =================
    http = []
    for entry in raw_http:
        # Legacy string support
        if isinstance(entry, str):
            http.append({
                "src": "unknown",
                "dst": "unknown",
                "raw": entry
            })
        # Structured (future-safe)
        elif isinstance(entry, dict):
            http.append({
                "src": entry.get("src", "unknown"),
                "dst": entry.get("dst", "unknown"),
                "raw": entry.get("raw", "")
            })

    # ================= Risk (TEMP, FACT-BASED) =================
    risk = "LOW"
    if auth.get("credentials"):
        risk = "HIGH"
    elif auth.get("bruteforce_indicators"):
        risk = "MEDIUM"

    # ================= Final structured output =================
    return {
        "meta": {
            "file": os.path.basename(pcap_file),
            "total_packets": len(packets),
            "duration": duration,
            "risk": risk,
        },
        "protocols": protocols,
        "flows": flows,
        "timeline": timeline,
        "signals": {
            "icmp": icmp,
            "arp": arp,
        },
        "auth": auth,
        "index": {
            "ips": sorted(ips),
            "ports": ports_info["ports"],
            "services": ports_info["services"],
            "connections": ports_info["connections"],
            "dns": dns,
            "http": http,     # ✅ ALWAYS DICT NOW
            "tls": tls,
        },
    }
