from __future__ import annotations

import ipaddress
from collections.abc import Iterable

from .models import LogEvent


ENTITY_FIELDS: dict[str, tuple[str, ...]] = {
    "ip": ("srcip", "src_ip", "source_ip", "client_ip", "remote_addr", "remote_ip", "ip", "ipaddress", "winlog_event_data_ipaddress", "event_data_ipaddress"),
    "user": ("username", "user", "user_name", "account", "account_name", "targetusername", "subjectusername", "xauthuser", "winlog_event_data_targetusername", "winlog_event_data_subjectusername"),
    "host": ("hostname", "host", "computer", "computer_name", "workstation", "device_name", "winlog_computer_name", "agent_name"),
}


def entity_type(value: str) -> str:
    try:
        ipaddress.ip_address(value)
        return "ip"
    except ValueError:
        return "entity"


def event_entities(event: LogEvent) -> list[dict[str, str]]:
    """Return normalized identities shared across network, endpoint, DNS, and web logs."""
    identities: list[dict[str, str]] = []
    seen: set[tuple[str, str]] = set()
    for kind, fields in ENTITY_FIELDS.items():
        for field in fields:
            value = str(event.fields.get(field, "")).strip()
            if not value or value in {"-", "unknown", "n/a"}:
                continue
            key = (kind, value.lower() if kind != "ip" else value)
            if key not in seen:
                seen.add(key)
                identities.append({"entity": value, "entity_type": kind, "field": field})
    return identities


def profile_entity(event: LogEvent, field: str) -> str:
    return str(event.fields.get(field.lower(), "")).strip()


def sample_timeline(events: Iterable[LogEvent], *, limit: int = 20) -> list[dict[str, str]]:
    samples = [
        {
            "stream": event.fields.get("fgai_stream", "local_syslog"),
            "timestamp": event.fields.get("eventtime", event.fields.get("timestamp", "")),
            "type": event.fields.get("type", ""),
            "subtype": event.subtype,
            "action": event.action,
            "severity": event.severity,
            "destination": event.dst_ip or event.fields.get("query_domain", event.fields.get("url", "")),
            "service": event.fields.get("service", event.fields.get("query_type", "")),
            "context": event.fields.get("query_domain", event.fields.get("qh", event.fields.get("url", event.fields.get("message", event.fields.get("msg", "")))))[:240],
        }
        for event in events
    ]
    return sorted(samples, key=lambda item: item["timestamp"])[-limit:]
