from __future__ import annotations

from dataclasses import dataclass
from typing import Callable, Iterable, Sequence, List

from .model import Finding, ScanRequest


@dataclass(frozen=True)
class CheckModule:
    """
    Declarative description of a diagnostic module executed by the scanner orchestrator.
    """

    name: str
    description: str
    runner: Callable[[ScanRequest], Iterable[Finding]]
    tags: Sequence[str] = ()


def build_default_modules() -> List[CheckModule]:
    from .checks.headers import evaluate_security_headers
    from .checks.injection import evaluate_injection_surface
    from .checks.osint import evaluate_osint_footprint
    from .checks.third_party import evaluate_third_party_integrations
    from .checks.tls import evaluate_tls

    modules = [
        CheckModule(
            name="tls",
            description="TLS certificate hygiene (expiry, hostname coverage).",
            runner=evaluate_tls,
            tags=("passive", "network"),
        ),
        CheckModule(
            name="headers",
            description="HTTP response hardening headers and secure cookies.",
            runner=evaluate_security_headers,
            tags=("passive", "http"),
        ),
        CheckModule(
            name="injection",
            description="Benign payload probes for SQL/XSS indicators.",
            runner=evaluate_injection_surface,
            tags=("active", "payloads"),
        ),
        CheckModule(
            name="third-party",
            description="Delegation stubs for OWASP ZAP, Burp Suite, Nikto APIs.",
            runner=evaluate_third_party_integrations,
            tags=("integration",),
        ),
        CheckModule(
            name="osint",
            description="Open Source Intelligence reconnaissance for public exposure footprint.",
            runner=evaluate_osint_footprint,
            tags=("passive", "reconnaissance", "intelligence"),
        ),
    ]
    
    # Try to import static analysis module (requires BeautifulSoup4)
    try:
        from .checks.static_analysis import evaluate_dom_surface
        modules.append(
            CheckModule(
                name="static-analysis",
                description="DOM heuristics for reflected XSS/CSRF token coverage.",
                runner=evaluate_dom_surface,
                tags=("passive", "dom"),
            )
        )
    except ImportError:
        # BeautifulSoup4 not available, skip static analysis module
        pass
    
    # Add backend configuration analysis modules
    try:
        from .checks.backend_config import evaluate_backend_configuration
        modules.append(
            CheckModule(
                name="backend-config",
                description="Backend security configuration analysis via public endpoints.",
                runner=evaluate_backend_configuration,
                tags=("active", "backend", "configuration"),
            )
        )
    except ImportError:
        pass
    
    try:
        from .checks.api_security import evaluate_api_security
        modules.append(
            CheckModule(
                name="api-security",
                description="REST/GraphQL API security analysis and endpoint discovery.",
                runner=evaluate_api_security,
                tags=("active", "api", "security"),
            )
        )
    except ImportError:
        pass
    
    try:
        from .checks.modern_web import evaluate_modern_web_technologies
        modules.append(
            CheckModule(
                name="modern-web",
                description="Modern web technologies analysis (SPA, PWA, frameworks).",
                runner=evaluate_modern_web_technologies,
                tags=("passive", "frontend", "frameworks"),
            )
        )
    except ImportError:
        pass
    
    # Add source code analysis module (SAST)
    try:
        from .checks.source_code import evaluate_source_code
        modules.append(
            CheckModule(
                name="source-code",
                description="Static Application Security Testing (SAST) for source code vulnerabilities.",
                runner=evaluate_source_code,
                tags=("sast", "static", "premium"),
            )
        )
    except ImportError:
        pass
    
    return modules
