"""Integration tests for F5 iControl REST API tools.

Verifies correct URL construction, token-based auth, SSL, timeout, and payload
by inspecting how requests.post (login) and requests.request (data) are called.
"""


class TestF5ListUrlConstruction:
    """Verify f5_list builds correct URLs."""

    def test_url_with_object_name(self, mock_f5_credentials, mock_f5_requests):
        """URL includes object type and name."""
        from mcp_network_jcd.tools.f5 import f5_list

        f5_list(host="10.0.0.1", object_type="pool", object_name="mypool")

        mock_f5_requests.assert_called_once()
        call_args = mock_f5_requests.call_args
        assert call_args[0][0] == "GET"
        assert call_args[0][1] == "https://10.0.0.1/mgmt/tm/ltm/pool/mypool"

    def test_url_without_object_name(self, mock_f5_credentials, mock_f5_requests):
        """URL lists all objects when name is empty."""
        from mcp_network_jcd.tools.f5 import f5_list

        f5_list(host="10.0.0.1", object_type="virtual")

        call_args = mock_f5_requests.call_args
        assert call_args[0][1] == "https://10.0.0.1/mgmt/tm/ltm/virtual"

    def test_url_irule_type(self, mock_f5_credentials, mock_f5_requests):
        """URL correctly uses irule type."""
        from mcp_network_jcd.tools.f5 import f5_list

        f5_list(host="10.0.0.1", object_type="irule", object_name="my_irule")

        call_args = mock_f5_requests.call_args
        assert call_args[0][1] == "https://10.0.0.1/mgmt/tm/ltm/irule/my_irule"


class TestF5SubCollectionUrlConstruction:
    """Verify f5_list builds correct URLs for sub-collections."""

    def test_url_pool_members(self, mock_f5_credentials, mock_f5_requests):
        """URL includes pool name and /members suffix."""
        from mcp_network_jcd.tools.f5 import f5_list

        f5_list(
            host="10.0.0.1",
            object_type="pool",
            object_name="mypool",
            sub_collection="members",
        )

        call_args = mock_f5_requests.call_args
        assert call_args[0][0] == "GET"
        assert call_args[0][1] == "https://10.0.0.1/mgmt/tm/ltm/pool/mypool/members"

    def test_url_virtual_policies(self, mock_f5_credentials, mock_f5_requests):
        """URL includes virtual name and /policies suffix."""
        from mcp_network_jcd.tools.f5 import f5_list

        f5_list(
            host="10.0.0.1",
            object_type="virtual",
            object_name="myvip",
            sub_collection="policies",
        )

        call_args = mock_f5_requests.call_args
        assert call_args[0][1] == "https://10.0.0.1/mgmt/tm/ltm/virtual/myvip/policies"

    def test_url_virtual_profiles(self, mock_f5_credentials, mock_f5_requests):
        """URL includes virtual name and /profiles suffix."""
        from mcp_network_jcd.tools.f5 import f5_list

        f5_list(
            host="10.0.0.1",
            object_type="virtual",
            object_name="myvip",
            sub_collection="profiles",
        )

        call_args = mock_f5_requests.call_args
        assert call_args[0][1] == "https://10.0.0.1/mgmt/tm/ltm/virtual/myvip/profiles"


class TestF5StatsUrlConstruction:
    """Verify f5_stats builds correct URLs."""

    def test_url_includes_stats_suffix(self, mock_f5_credentials, mock_f5_requests):
        """URL includes /stats at the end."""
        from mcp_network_jcd.tools.f5 import f5_stats

        f5_stats(host="10.0.0.1", object_type="virtual", object_name="myvip")

        call_args = mock_f5_requests.call_args
        assert call_args[0][0] == "GET"
        assert call_args[0][1] == "https://10.0.0.1/mgmt/tm/ltm/virtual/myvip/stats"


class TestF5TokenAuth:
    """Verify token-based authentication flow."""

    def test_login_called_with_credentials(self, mock_f5_credentials, mock_f5_requests, mocker):
        """Login POST is called with correct credentials."""
        from mcp_network_jcd.tools.f5 import f5_list

        mock_post = mocker.patch("mcp_network_jcd.tools.f5.requests.post")
        mock_login_resp = mocker.MagicMock()
        mock_login_resp.status_code = 200
        mock_login_resp.json.return_value = {"token": {"token": "TEST_TOKEN"}}
        mock_login_resp.raise_for_status.return_value = None
        mock_post.return_value = mock_login_resp

        f5_list(host="10.0.0.1", object_type="pool", object_name="test")

        mock_post.assert_called_once()
        call_kwargs = mock_post.call_args[1]
        assert call_kwargs["json"]["username"] == "admin"
        assert call_kwargs["json"]["password"] == "f5secret"

    def test_token_used_in_request_header(self, mock_f5_credentials, mock_f5_requests, mocker):
        """Data request uses X-F5-Auth-Token header from login."""
        from mcp_network_jcd.tools.f5 import f5_list

        mock_post = mocker.patch("mcp_network_jcd.tools.f5.requests.post")
        mock_login_resp = mocker.MagicMock()
        mock_login_resp.status_code = 200
        mock_login_resp.json.return_value = {"token": {"token": "MY_AUTH_TOKEN"}}
        mock_login_resp.raise_for_status.return_value = None
        mock_post.return_value = mock_login_resp

        f5_list(host="10.0.0.1", object_type="pool", object_name="test")

        call_kwargs = mock_f5_requests.call_args[1]
        assert call_kwargs["headers"]["X-F5-Auth-Token"] == "MY_AUTH_TOKEN"

    def test_login_url_correct(self, mock_f5_credentials, mock_f5_requests, mocker):
        """Login POST targets /mgmt/shared/authn/login."""
        from mcp_network_jcd.tools.f5 import f5_list

        mock_post = mocker.patch("mcp_network_jcd.tools.f5.requests.post")
        mock_login_resp = mocker.MagicMock()
        mock_login_resp.status_code = 200
        mock_login_resp.json.return_value = {"token": {"token": "TOK"}}
        mock_login_resp.raise_for_status.return_value = None
        mock_post.return_value = mock_login_resp

        f5_list(host="10.0.0.1", object_type="pool")

        assert mock_post.call_args[0][0] == "https://10.0.0.1/mgmt/shared/authn/login"


class TestF5SslVerification:
    """Verify SSL verification is disabled."""

    def test_verify_is_false_on_request(self, mock_f5_credentials, mock_f5_requests):
        """Data request has verify=False for self-signed certs."""
        from mcp_network_jcd.tools.f5 import f5_list

        f5_list(host="10.0.0.1", object_type="pool", object_name="test")

        call_kwargs = mock_f5_requests.call_args[1]
        assert call_kwargs["verify"] is False


class TestF5ProxyDisabled:
    """Verify proxy is disabled for direct access."""

    def test_proxies_empty_on_request(self, mock_f5_credentials, mock_f5_requests):
        """Data request has empty proxies dict to bypass proxy."""
        from mcp_network_jcd.tools.f5 import f5_list

        f5_list(host="10.0.0.1", object_type="pool", object_name="test")

        call_kwargs = mock_f5_requests.call_args[1]
        assert call_kwargs["proxies"] == {"http": "", "https": ""}


class TestF5Timeout:
    """Verify timeout is passed correctly."""

    def test_custom_timeout(self, mock_f5_credentials, mock_f5_requests):
        """Custom timeout value is forwarded to requests."""
        from mcp_network_jcd.tools.f5 import f5_list

        f5_list(host="10.0.0.1", object_type="pool", object_name="test", timeout=60)

        call_kwargs = mock_f5_requests.call_args[1]
        assert call_kwargs["timeout"] == 60

    def test_default_timeout(self, mock_f5_credentials, mock_f5_requests):
        """Default timeout is 20 seconds."""
        from mcp_network_jcd.tools.f5 import f5_stats

        f5_stats(host="10.0.0.1", object_type="pool", object_name="test")

        call_kwargs = mock_f5_requests.call_args[1]
        assert call_kwargs["timeout"] == 20
