"""
Security Middleware for Cache Control and Security Headers
"""
from typing import Callable

from fastapi import Request, Response
from starlette.middleware.base import BaseHTTPMiddleware

from src.core.config import settings


class SecurityMiddleware(BaseHTTPMiddleware):
    """
    Middleware to add security headers and prevent caching of sensitive information.
    
    Security headers added:
    - Cache-Control: Prevents caching
    - Pragma: Additional cache prevention (legacy support)
    - Expires: Ensures content expires immediately
    - Permissions-Policy: Controls browser permissions
    - Content-Security-Policy: Frame security (production only)
    """
    
    def __init__(self, app, add_csp: bool = True, add_permissions_policy: bool = True):
        super().__init__(app)
        self.add_csp = add_csp
        self.add_permissions_policy = add_permissions_policy
    
    async def dispatch(self, request: Request, call_next: Callable) -> Response:
        """Add security headers to response"""
        response = await call_next(request)
        
        # Prevent caching of sensitive information
        response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
        response.headers["Pragma"] = "no-cache"
        response.headers["Expires"] = "0"
        
        # Add permissions policy to restrict browser features
        if self.add_permissions_policy:
            response.headers["Permissions-Policy"] = (
                "camera=(), microphone=(), geolocation=(), payment=()"
            )
        
        # Add Content Security Policy for production
        if self.add_csp and settings.APP_ENV == "prod":
            response.headers["Content-Security-Policy"] = (
                "frame-ancestors 'self' *.yourdomain.com; "
                "default-src 'self'; "
                "script-src 'self' 'unsafe-inline' 'unsafe-eval'; "
                "style-src 'self' 'unsafe-inline'; "
                "img-src 'self' data: https:; "
                "font-src 'self' data:; "
                "connect-src 'self'"
            )
        
        # Add X-Frame-Options for additional frame protection
        response.headers["X-Frame-Options"] = "SAMEORIGIN"
        
        # Add X-Content-Type-Options to prevent MIME sniffing
        response.headers["X-Content-Type-Options"] = "nosniff"
        
        # Add X-XSS-Protection (legacy browsers)
        response.headers["X-XSS-Protection"] = "1; mode=block"
        
        return response


class NoCacheMiddleware(BaseHTTPMiddleware):
    """
    Simplified middleware focused only on preventing caching.
    
    Use this when you only need cache control without other security headers.
    """
    
    async def dispatch(self, request: Request, call_next: Callable) -> Response:
        """Add cache prevention headers to response"""
        response = await call_next(request)
        
        # Set headers to prevent caching of sensitive information
        response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
        response.headers["Pragma"] = "no-cache"
        response.headers["Expires"] = "0"
        
        # Basic permissions policy for common restrictions
        response.headers["Permissions-Policy"] = (
            "camera=(), microphone=()"
        )
        
        # Production-specific CSP
        if settings.APP_ENV == "prod":
            response.headers["Content-Security-Policy"] = (
                "frame-ancestors 'self' *.yourdomain.com"  # Update with your domain
            )
        
        return response
