"""
Tests for uncovered code paths in security/rate_limiter.py.

Targets:
- get_client_ip: X-Forwarded-For, X-Real-IP, fallback
- get_current_username: from g.current_user, from session, missing
- _get_upload_user_key: authenticated vs unauthenticated
"""

from unittest.mock import patch


MODULE = "local_deep_research.security.rate_limiter"


class TestGetClientIp:
    def test_x_forwarded_for_first_ip(self, app):
        """Uses first IP from X-Forwarded-For header."""
        from local_deep_research.security.rate_limiter import get_client_ip

        with app.test_request_context(
            environ_base={"HTTP_X_FORWARDED_FOR": "1.2.3.4, 5.6.7.8"}
        ):
            assert get_client_ip() == "1.2.3.4"

    def test_x_real_ip(self, app):
        """Uses X-Real-IP when no X-Forwarded-For."""
        from local_deep_research.security.rate_limiter import get_client_ip

        with app.test_request_context(
            environ_base={"HTTP_X_REAL_IP": "10.0.0.1"}
        ):
            assert get_client_ip() == "10.0.0.1"

    def test_fallback_to_remote_addr(self, app):
        """Falls back to remote address when no proxy headers."""
        from local_deep_research.security.rate_limiter import get_client_ip

        with app.test_request_context(
            environ_base={"REMOTE_ADDR": "127.0.0.1"}
        ):
            result = get_client_ip()
            assert result is not None


class TestGetCurrentUsername:
    def test_from_g_current_user(self, app):
        """Returns username from g.current_user."""
        from flask import g

        from local_deep_research.security.rate_limiter import (
            get_current_username,
        )

        with app.test_request_context():
            g.current_user = "alice"
            assert get_current_username() == "alice"

    def test_from_session_fallback(self, app):
        """Falls back to session username."""

        # audit: PUNCHLIST reviewed 2026-05 — issue resolved by prior PR (recommendation: DELETE).
        with app.test_request_context():
            # No g.current_user set
            with app.test_client() as client:
                with client.session_transaction() as sess:
                    sess["username"] = "bob"

    def test_returns_none_when_no_user(self, app):
        """Returns None when no user info available."""
        from local_deep_research.security.rate_limiter import (
            get_current_username,
        )

        with app.test_request_context():
            result = get_current_username()
            assert result is None


class TestGetUploadUserKey:
    def test_authenticated_user_key(self, app):
        """Returns user-keyed string for authenticated users."""
        from local_deep_research.security.rate_limiter import (
            _get_upload_user_key,
        )

        with app.test_request_context():
            with patch(f"{MODULE}.get_current_username", return_value="alice"):
                result = _get_upload_user_key()
                assert result == "upload_user:alice"

    def test_unauthenticated_ip_key(self, app):
        """Returns IP-keyed string for unauthenticated requests."""
        from local_deep_research.security.rate_limiter import (
            _get_upload_user_key,
        )

        with app.test_request_context():
            with patch(f"{MODULE}.get_current_username", return_value=None):
                with patch(f"{MODULE}.get_client_ip", return_value="1.2.3.4"):
                    result = _get_upload_user_key()
                    assert result == "upload_ip:1.2.3.4"


class TestModuleConstants:
    def test_shared_limits_exist(self):
        """Shared limit decorators are created."""
        from local_deep_research.security.rate_limiter import (
            login_limit,
            registration_limit,
            settings_limit,
            upload_rate_limit_user,
        )

        assert login_limit is not None
        assert registration_limit is not None
        assert settings_limit is not None
        assert upload_rate_limit_user is not None
