from __future__ import annotations

import logging

import httpx

from cve_mcp.cache.sqlite_cache import VulnCache
from cve_mcp.config import MAX_RESPONSE_BYTES, THREATFOX_BASE

logger = logging.getLogger(__name__)

TTL_MALWARE = 3600  # 1 hour


async def lookup_malware_family(
    ioc: str,
    client: httpx.AsyncClient,
    cache: VulnCache,
) -> dict:
    """Look up an IOC (hash, IP, domain, URL) against ThreatFox for malware family info."""
    cache_key = f"threatfox:{ioc}"
    cached = await cache.get(cache_key)
    if cached is not None:
        return cached

    result: dict = {
        "ioc": ioc,
        "malware_family": "",
        "confidence": 0,
        "ioc_type": "",
        "tags": [],
        "threat_type": "",
        "malware_alias": "",
        "reference": "",
        "first_seen": "",
        "last_seen": "",
        "found": False,
    }

    try:
        resp = await client.post(
            f"{THREATFOX_BASE}/",
            json={"query": "search_ioc", "search_term": ioc},
        )

        content_length = resp.headers.get("content-length")
        if content_length and int(content_length) > MAX_RESPONSE_BYTES:
            raise ValueError("ThreatFox response too large (Content-Length)")
        if len(resp.content) > MAX_RESPONSE_BYTES:
            raise ValueError("ThreatFox response too large (actual body)")

        if resp.status_code == 200:
            body = resp.json()
            status = body.get("query_status", "")

            if status == "ok" and body.get("data"):
                entry = body["data"][0]
                result["found"] = True
                result["ioc_type"] = entry.get("ioc_type", "")
                result["malware_family"] = entry.get("malware_printable", "")
                result["malware_alias"] = entry.get("malware_alias") or ""
                result["confidence"] = entry.get("confidence_level", 0)
                result["tags"] = entry.get("tags") or []
                result["threat_type"] = entry.get("threat_type", "")
                result["reference"] = entry.get("reference") or ""
                result["first_seen"] = entry.get("first_seen", "")
                result["last_seen"] = entry.get("last_seen", "")
            # "no_result" means IOC not found — not an error

    except Exception as exc:
        logger.warning("ThreatFox error for %s: %s", ioc, exc)

    await cache.set(cache_key, result, TTL_MALWARE)
    return result
