"""WSGI middleware classes for web-layer security.

These wrap the Flask WSGI app to enforce cookie security and strip
information-disclosure headers. Wired into the middleware stack by
``local_deep_research.web.app_factory.create_app``.
"""

from loguru import logger

from .network_utils import is_private_ip


class SecureCookieMiddleware:
    """WSGI middleware that adds the Secure flag to Set-Cookie iff the
    request is HTTPS.

    The Secure flag tells the browser to send the cookie only over HTTPS.
    Setting it on a response served over HTTP causes the browser to drop
    the cookie entirely, so it must only be added when the user's
    connection is actually HTTPS. ``ProxyFix`` (with ``x_proto=1``)
    translates ``X-Forwarded-Proto`` into ``wsgi.url_scheme`` before this
    middleware runs.

    Side effect: logs a one-shot warning when the app serves HTTP to a
    non-private end-user IP, signalling a likely missing HTTPS proxy
    configuration. Skipped in ``LDR_TESTING_MODE``.
    """

    def __init__(self, wsgi_app, flask_app):
        self.wsgi_app = wsgi_app
        self.flask_app = flask_app
        self._warned_insecure_public = False

    def __call__(self, environ, start_response):
        self._maybe_warn_insecure_public(environ)
        should_add_secure = self._should_add_secure_flag(environ)

        def custom_start_response(status, headers, exc_info=None):
            if should_add_secure:
                new_headers = []
                for name, value in headers:
                    if name.lower() == "set-cookie":
                        if "; Secure" not in value and "; secure" not in value:
                            value = value + "; Secure"
                    new_headers.append((name, value))
                headers = new_headers
            return start_response(status, headers, exc_info)

        return self.wsgi_app(environ, custom_start_response)

    def _should_add_secure_flag(self, environ):
        if self.flask_app.config.get("LDR_TESTING_MODE"):
            return False
        return environ.get("wsgi.url_scheme") == "https"

    def _maybe_warn_insecure_public(self, environ):
        if self._warned_insecure_public:
            return
        if self.flask_app.config.get("LDR_TESTING_MODE"):
            return
        if environ.get("wsgi.url_scheme") == "https":
            return
        remote_addr = environ.get("REMOTE_ADDR", "")
        if is_private_ip(remote_addr):
            return
        self._warned_insecure_public = True
        logger.warning(
            f"Serving HTTP to non-private client {remote_addr}. "
            f"Session cookies will be sent in plaintext. Configure HTTPS "
            f"at the reverse proxy and ensure X-Forwarded-Proto is set."
        )


class ServerHeaderMiddleware:
    """WSGI middleware that strips the Server header from responses to
    prevent information disclosure about the underlying web server.
    Applied as the outermost wrapper.
    """

    def __init__(self, wsgi_app):
        self.wsgi_app = wsgi_app

    def __call__(self, environ, start_response):
        def custom_start_response(status, headers, exc_info=None):
            filtered_headers = [
                (name, value)
                for name, value in headers
                if name.lower() != "server"
            ]
            return start_response(status, filtered_headers, exc_info)

        return self.wsgi_app(environ, custom_start_response)
