from __future__ import annotations

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

from .localization import t
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=t("modules.tls.description"),
            runner=evaluate_tls,
            tags=("passive", "network"),
        ),
        CheckModule(
            name="headers",
            description=t("modules.headers.description"),
            runner=evaluate_security_headers,
            tags=("passive", "http"),
        ),
        CheckModule(
            name="injection",
            description=t("modules.injection.description"),
            runner=evaluate_injection_surface,
            tags=("active", "payloads"),
        ),
        CheckModule(
            name="third-party",
            description=t("modules.third_party.description"),
            runner=evaluate_third_party_integrations,
            tags=("integration",),
        ),
        CheckModule(
            name="osint",
            description=t("modules.osint.description"),
            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=t("modules.static_analysis.description"),
                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=t("modules.backend_config.description"),
                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=t("modules.api_security.description"),
                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=t("modules.modern_web.description"),
                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=t("modules.source_code.description"),
                runner=evaluate_source_code,
                tags=("sast", "static", "premium"),
            )
        )
    except ImportError:
        pass
    
    # Add new OWASP Top 10 2021 security modules
    try:
        from .checks.owasp_security_modules import evaluate_access_control
        modules.append(
            CheckModule(
                name="access-control",
                description=t("modules.access_control.description"),
                runner=evaluate_access_control,
                tags=("passive", "authorization", "owasp-a01"),
            )
        )
    except ImportError:
        pass
    
    try:
        from .checks.owasp_security_modules import evaluate_cryptographic_failures
        modules.append(
            CheckModule(
                name="crypto-failures",
                description=t("modules.crypto_failures.description"),
                runner=evaluate_cryptographic_failures,
                tags=("passive", "cryptography", "owasp-a02"),
            )
        )
    except ImportError:
        pass
    
    try:
        from .checks.owasp_security_modules import evaluate_vulnerable_components
        modules.append(
            CheckModule(
                name="vulnerable-components",
                description=t("modules.vulnerable_components.description"),
                runner=evaluate_vulnerable_components,
                tags=("passive", "dependencies", "owasp-a06"),
            )
        )
    except ImportError:
        pass
    
    try:
        from .checks.owasp_security_modules import evaluate_insecure_design
        modules.append(
            CheckModule(
                name="insecure-design",
                description=t("modules.insecure_design.description"),
                runner=evaluate_insecure_design,
                tags=("passive", "architecture", "owasp-a04"),
            )
        )
    except ImportError:
        pass
    
    try:
        from .checks.owasp_security_modules import evaluate_security_misconfiguration
        modules.append(
            CheckModule(
                name="security-misconfiguration",
                description=t("modules.security_misconfiguration.description"),
                runner=evaluate_security_misconfiguration,
                tags=("passive", "configuration", "owasp-a05"),
            )
        )
    except ImportError:
        pass
    
    try:
        from .checks.owasp_security_modules import evaluate_broken_authentication
        modules.append(
            CheckModule(
                name="broken-authentication",
                description=t("modules.broken_authentication.description"),
                runner=evaluate_broken_authentication,
                tags=("passive", "authentication", "owasp-a07"),
            )
        )
    except ImportError:
        pass
    
    return modules
