from __future__ import annotations
from dataclasses import dataclass, field
from typing import Dict, List, Optional


@dataclass
class DmarcInfo:
    present: bool = False
    raw_records: List[str] = field(default_factory=list)
    policy: Optional[str] = None
    pct: Optional[int] = None
    rua_present: Optional[bool] = None
    adkim: Optional[str] = None
    aspf: Optional[str] = None
    ambiguous: bool = False
    parse_error: Optional[str] = None


@dataclass
class SpfInfo:
    present: bool = False
    raw_records: List[str] = field(default_factory=list)
    spf_records_only: List[str] = field(default_factory=list) 
    multiple: bool = False
    all_qualifier: Optional[str] = None
    weak_all: bool = False
    parse_error: Optional[str] = None


@dataclass
class MxInfo:
    present: bool = False
    exchanges: List[str] = field(default_factory=list)


@dataclass
class DkimInfo:
    probed: bool = False
    found_selectors: List[str] = field(default_factory=list)
    notes: Optional[str] = None


@dataclass
class SyntaxInfo:
    input_domain: str = ""
    fqdn_provided: bool = False
    registrable_domain: str = ""
    subdomain: str = ""
    idn: bool = False
    mixed_scripts: bool = False
    suspicious_tokens: List[str] = field(default_factory=list)
    brand_in_subdomain: List[str] = field(default_factory=list)
    typo_matches: List[Dict[str, object]] = field(default_factory=list)


@dataclass
class Result:
    domain_input: str
    etld_plus_one: str
    risk_score: int
    risk_level: str
    reasons: List[str]
    syntax: SyntaxInfo
    mx: MxInfo
    dmarc: DmarcInfo
    spf: SpfInfo
    dkim: DkimInfo
    timestamp_utc: str
