"""Public DNS checks via dig (read-only)."""

from __future__ import annotations

import subprocess
from typing import Any


def _dig(*args: str) -> list[str]:
    try:
        proc = subprocess.run(
            ["dig", "+short", *args],
            capture_output=True,
            text=True,
            timeout=8,
        )
        if proc.returncode != 0:
            return []
        lines = [ln.strip().strip('"') for ln in proc.stdout.splitlines() if ln.strip()]
        return lines
    except Exception:
        return []


def _result(check_id: str, label: str, status: str, message: str, evidence: dict | None = None) -> dict[str, Any]:
    return {
        "check_id": check_id,
        "label": label,
        "status": status,
        "message": message,
        "evidence": evidence or {},
    }


def collect(domain: str, mail_public_ip: str | None = None) -> dict[str, dict[str, Any]]:
    domain = domain.lower().strip()
    mail_host = f"mail.{domain}"
    results: dict[str, dict[str, Any]] = {}

    mx = _dig(domain, "MX")
    mx_ok = any(mail_host in line or domain in line for line in mx)
    results["dns_mx"] = _result(
        "dns_mx",
        "MX record",
        "pass" if mx_ok else "fail",
        f"MX: {', '.join(mx[:3]) or 'none'}",
        {"records": mx},
    )

    txt_root = _dig(domain, "TXT")
    spf = [t for t in txt_root if t.lower().startswith("v=spf1")]
    results["dns_spf"] = _result(
        "dns_spf",
        "SPF",
        "pass" if spf else "fail",
        spf[0][:120] if spf else "SPF TXT not found",
        {"records": spf},
    )

    dkim_name = f"default._domainkey.{domain}"
    dkim = _dig(dkim_name, "TXT")
    results["dns_dkim"] = _result(
        "dns_dkim",
        "DKIM",
        "pass" if dkim else "fail",
        "DKIM TXT present" if dkim else f"{dkim_name} not found",
        {"records": dkim[:2]},
    )

    dmarc_name = f"_dmarc.{domain}"
    dmarc = _dig(dmarc_name, "TXT")
    results["dns_dmarc"] = _result(
        "dns_dmarc",
        "DMARC",
        "pass" if dmarc else "warn",
        dmarc[0][:120] if dmarc else "DMARC TXT not found",
        {"records": dmarc},
    )

    if mail_public_ip:
        a_mail = _dig(mail_host, "A")
        if mail_public_ip not in a_mail and results["dns_mx"]["status"] == "pass":
            results["dns_mx"]["status"] = "warn"
            results["dns_mx"]["message"] += f" (A {mail_host}: {a_mail or 'none'})"

    return results
