File size: 2,903 Bytes
89419ea
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
"""Domain resolution helpers for Temp-Mail service."""

from __future__ import annotations

import logging
from typing import Any, Callable, Dict, Iterable, List, Optional, Sequence, Tuple

logger = logging.getLogger(__name__)

DomainFetcher = Callable[[], Any]


def normalize_domains(value: Any) -> List[str]:
    """Normalize domains from list/string payload into unique ordered list."""
    if value is None:
        return []

    values: Iterable[Any]
    if isinstance(value, str):
        values = [part.strip() for part in value.split(",")]
    elif isinstance(value, Sequence):
        values = value
    else:
        return []

    seen = set()
    domains: List[str] = []
    for item in values:
        text = str(item or "").strip().lower()
        if not text:
            continue
        if "." not in text:
            continue
        if text in seen:
            continue
        seen.add(text)
        domains.append(text)
    return domains


def _domains_from_worker_response(payload: Any) -> List[str]:
    if isinstance(payload, dict):
        return normalize_domains(payload.get("domains"))
    return normalize_domains(payload)


def _resolve_with_source(config: Optional[Dict[str, Any]], fetch_domains: Optional[DomainFetcher]) -> Tuple[List[str], str]:
    cfg = config or {}

    configured_pool = normalize_domains(cfg.get("domains"))
    if configured_pool:
        return configured_pool, "config_domains"

    if fetch_domains is not None:
        try:
            worker_domains = _domains_from_worker_response(fetch_domains())
            if worker_domains:
                return worker_domains, "worker_api"
        except Exception as exc:  # pragma: no cover - exercised via tests
            logger.debug("Temp-Mail domains endpoint unavailable, fallback to config.domain: %s", exc)

    fallback = normalize_domains(cfg.get("domain"))
    if fallback:
        return fallback, "config_fallback"

    return [], "none"


def resolve_temp_mail_domains(
    config: Optional[Dict[str, Any]],
    *,
    fetch_domains: Optional[DomainFetcher] = None,
) -> List[str]:
    """Resolve available domains for a temp_mail service config."""
    domains, _ = _resolve_with_source(config, fetch_domains)
    return domains


def summarize_temp_mail_domains(
    config: Optional[Dict[str, Any]],
    *,
    fetch_domains: Optional[DomainFetcher] = None,
    preview_limit: int = 3,
) -> Dict[str, Any]:
    """Build safe domain summary for API output/capabilities."""
    domains, source = _resolve_with_source(config, fetch_domains)
    preview_count = max(0, int(preview_limit))
    preview = domains[:preview_count] if preview_count else []
    primary = domains[0] if domains else None
    return {
        "domain": primary,
        "domain_count": len(domains),
        "domains_preview": preview,
        "domain_source": source,
        "domains": domains,
    }