"""TLS/SSL certificate analysis."""
import asyncio
import ssl
import socket
from typing import Dict, Optional

from reclaimor.config import Config
from reclaimor.utils.logger import setup_logger

logger = setup_logger(__name__)


class TLSChecker:
    """TLS certificate analysis for subdomain takeover indicators."""
    
    def __init__(self, config: Config):
        self.config = config
    
    async def check(self, domain: str) -> Optional[Dict]:
        """
        Analyze TLS certificate for takeover indicators.
        
        Returns dict with:
            - issuer: str
            - subject: str
            - san: list of Subject Alternative Names
            - mismatch: bool (domain not in cert)
            - error: str or None
        """
        try:
            loop = asyncio.get_event_loop()
            cert_info = await loop.run_in_executor(
                None, self._get_cert_info, domain
            )
            return cert_info
        except Exception as e:
            logger.debug(f"TLS check error for {domain}: {e}")
            return {"error": str(e), "mismatch": False}
    
    def _get_cert_info(self, domain: str) -> Dict:
        """Get certificate information (blocking call)."""
        context = ssl.create_default_context()
        context.check_hostname = False
        context.verify_mode = ssl.CERT_NONE
        
        try:
            with socket.create_connection((domain, 443), timeout=self.config.timeout) as sock:
                with context.wrap_socket(sock, server_hostname=domain) as ssock:
                    cert = ssock.getpeercert()
                    
                    if not cert:
                        return {"error": "No certificate", "mismatch": False}
                    
                    # Extract certificate details
                    subject = dict(x[0] for x in cert.get("subject", []))
                    issuer = dict(x[0] for x in cert.get("issuer", []))
                    
                    # Get Subject Alternative Names
                    san = []
                    for key, value in cert.get("subjectAltName", []):
                        if key == "DNS":
                            san.append(value)
                    
                    # Check if domain matches certificate
                    cn = subject.get("commonName", "")
                    mismatch = domain not in san and domain != cn
                    
                    return {
                        "issuer": issuer.get("organizationName", "Unknown"),
                        "subject": cn,
                        "san": san,
                        "mismatch": mismatch,
                        "error": None,
                    }
        
        except (socket.timeout, socket.error, ssl.SSLError) as e:
            return {"error": str(e), "mismatch": False}
