"""Health helpers for {{ module_title }}."""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any, Dict, Iterable, Mapping

PolicyValue = str | Iterable[str] | None


@dataclass(slots=True)
class {{ module_class_name }}Config:
    enabled: bool = True
    strict_transport_security: bool = True
    strict_transport_security_max_age: int = 63072000
    strict_transport_security_include_subdomains: bool = True
    strict_transport_security_preload: bool = True
    content_security_policy: str | None = None
    content_security_policy_report_only: bool = False
    referrer_policy: str = "strict-origin-when-cross-origin"
    x_content_type_options: str | bool = "nosniff"
    x_frame_options: str = "DENY"
    x_xss_protection: bool = False
    cross_origin_embedder_policy: str | None = "require-corp"
    cross_origin_opener_policy: str | None = "same-origin"
    cross_origin_resource_policy: str | None = "same-origin"
    permissions_policy: Dict[str, PolicyValue] = field(default_factory=dict)
    expect_ct: str | None = None
    x_dns_prefetch_control: str | None = "off"
    x_download_options: str | None = "noopen"
    additional_headers: Dict[str, str] = field(default_factory=dict)


@dataclass(slots=True)
class {{ module_class_name }}Metrics:
    enabled: bool
    header_count: int
    missing: list[str] = field(default_factory=list)

    def as_dict(self) -> Dict[str, object]:
        return {
            "enabled": self.enabled,
            "header_count": self.header_count,
            "missing": list(self.missing),
        }


def _expected_headers(config: {{ module_class_name }}Config) -> Iterable[str]:
    if config.strict_transport_security:
        yield "Strict-Transport-Security"
    if config.x_content_type_options:
        yield "X-Content-Type-Options"
    if config.x_frame_options:
        yield "X-Frame-Options"
    if config.referrer_policy:
        yield "Referrer-Policy"
    if config.permissions_policy:
        yield "Permissions-Policy"
    if config.content_security_policy:
        header_name = (
            "Content-Security-Policy-Report-Only"
            if config.content_security_policy_report_only
            else "Content-Security-Policy"
        )
        yield header_name
    if config.cross_origin_embedder_policy:
        yield "Cross-Origin-Embedder-Policy"
    if config.cross_origin_opener_policy:
        yield "Cross-Origin-Opener-Policy"
    if config.cross_origin_resource_policy:
        yield "Cross-Origin-Resource-Policy"
    if config.expect_ct:
        yield "Expect-CT"
    if config.x_dns_prefetch_control:
        yield "X-DNS-Prefetch-Control"
    if config.x_download_options:
        yield "X-Download-Options"
    if config.x_xss_protection:
        yield "X-XSS-Protection"
    for name in config.additional_headers:
        yield name


def evaluate_completeness(
    config: {{ module_class_name }}Config, headers: Mapping[str, str]
) -> {{ module_class_name }}Metrics:
    expected = set(_expected_headers(config))
    present = set(headers)
    missing = sorted(expected - present)
    return {{ module_class_name }}Metrics(
        enabled=config.enabled,
        header_count=len(headers),
        missing=list(missing),
    )


def build_health_payload(
    *,
    module: str,
    status: str,
    headers: Mapping[str, str],
    metrics: {{ module_class_name }}Metrics,
    extra: Mapping[str, Any] | None = None,
) -> Dict[str, Any]:
    payload: Dict[str, Any] = {
        "module": module,
        "status": status,
        "headers": dict(sorted(headers.items())),
        "metrics": metrics.as_dict(),
    }
    if extra:
        payload.update(extra)
    return payload
