"""Shared pytest fixtures for MCP Network JCD tests."""

import pytest


@pytest.fixture
def mock_credentials(monkeypatch):
    """Mock Palo Alto credentials from environment variables."""
    monkeypatch.setenv("PALOALTO_USERNAME", "testuser")
    monkeypatch.setenv("PALOALTO_PASSWORD", "testpass")


@pytest.fixture
def mock_netmiko(mocker):
    """Mock netmiko ConnectHandler for SSH testing."""
    mock_handler = mocker.MagicMock()
    mock_handler.send_command.return_value = "hostname: test-fw\nserial: 001234567890"
    mock_handler.disconnect.return_value = None

    mock_connect = mocker.patch("netmiko.ConnectHandler", return_value=mock_handler)
    return mock_connect


@pytest.fixture
def sample_device_params():
    """Sample device connection parameters."""
    return {
        "host": "192.168.1.1",
        "port": 22,
        "timeout": 30,
    }


@pytest.fixture
def sample_commands():
    """Sample PAN-OS commands for testing."""
    return ["show system info", "show interface all"]


@pytest.fixture
def mock_cisco_credentials(monkeypatch):
    """Mock Cisco credentials from environment variables."""
    monkeypatch.setenv("CISCO_USERNAME", "testuser")
    monkeypatch.setenv("CISCO_PASSWORD", "testpass")
    monkeypatch.delenv("CISCO_ENABLE_PASSWORD", raising=False)


@pytest.fixture
def mock_cisco_credentials_with_enable(monkeypatch):
    """Mock Cisco credentials with enable password."""
    monkeypatch.setenv("CISCO_USERNAME", "testuser")
    monkeypatch.setenv("CISCO_PASSWORD", "testpass")
    monkeypatch.setenv("CISCO_ENABLE_PASSWORD", "enablesecret")


@pytest.fixture
def mock_cisco_netmiko(mocker):
    """Mock netmiko ConnectHandler for Cisco SSH testing."""
    mock_handler = mocker.MagicMock()
    mock_handler.send_command.return_value = "Cisco IOS Software, Version 15.1(4)M4"
    mock_handler.disconnect.return_value = None
    mock_handler.enable.return_value = None

    mock_connect = mocker.patch("netmiko.ConnectHandler", return_value=mock_handler)
    return mock_connect


@pytest.fixture
def mock_f5_credentials(monkeypatch):
    """Mock F5 credentials from environment variables."""
    monkeypatch.setenv("F5_USERNAME", "admin")
    monkeypatch.setenv("F5_PASSWORD", "f5secret")


@pytest.fixture
def mock_f5_requests(mocker):
    """Mock F5 token-based auth: login returns token, request returns data."""
    # Mock login (POST to /mgmt/shared/authn/login)
    mock_login_response = mocker.MagicMock()
    mock_login_response.status_code = 200
    mock_login_response.json.return_value = {"token": {"token": "FAKE_TOKEN_12345"}}
    mock_login_response.raise_for_status.return_value = None

    mocker.patch("mcp_network_jcd.tools.f5.requests.post", return_value=mock_login_response)

    # Mock data request (GET/POST to API endpoints)
    mock_response = mocker.MagicMock()
    mock_response.status_code = 200
    mock_response.json.return_value = {
        "kind": "tm:ltm:pool:poolstate",
        "name": "mypool",
        "items": [],
    }
    mock_response.text = '{"kind":"tm:ltm:pool:poolstate","name":"mypool","items":[]}'

    mock_req = mocker.patch(
        "mcp_network_jcd.tools.f5.requests.request", return_value=mock_response
    )
    return mock_req


@pytest.fixture
def mock_f5_requests_with_items(mocker):
    """Mock F5 requests returning realistic items for filtering tests."""
    mock_login_response = mocker.MagicMock()
    mock_login_response.status_code = 200
    mock_login_response.json.return_value = {"token": {"token": "FAKE_TOKEN_12345"}}
    mock_login_response.raise_for_status.return_value = None

    mocker.patch("mcp_network_jcd.tools.f5.requests.post", return_value=mock_login_response)

    mock_response = mocker.MagicMock()
    mock_response.status_code = 200
    mock_response.json.return_value = {
        "kind": "tm:ltm:virtual:virtualstate",
        "items": [
            {
                "name": "THOR-PRD-443_PLA",
                "fullPath": "/Common/THOR-PRD-443_PLA",
                "destination": "/Common/10.231.25.247:443",
            },
            {
                "name": "THOR-PRD-80_PLA",
                "fullPath": "/Common/THOR-PRD-80_PLA",
                "destination": "/Common/10.231.25.247:80",
            },
            {
                "name": "CHATJCD-PRD-443",
                "fullPath": "/Common/CHATJCD-PRD-443",
                "destination": "/Common/10.231.25.100:443",
            },
        ],
    }

    mocker.patch("mcp_network_jcd.tools.f5.requests.request", return_value=mock_response)


@pytest.fixture
def mock_f5_requests_401(mocker):
    """Mock F5 login returning HTTP 401 Unauthorized."""
    mock_login_response = mocker.MagicMock()
    mock_login_response.status_code = 401
    mock_login_response.text = '{"code":401,"message":"Authentication failed"}'

    mocker.patch("mcp_network_jcd.tools.f5.requests.post", return_value=mock_login_response)


@pytest.fixture
def mock_f5_requests_404(mocker):
    """Mock F5 login succeeds but data request returns HTTP 404."""
    mock_login_response = mocker.MagicMock()
    mock_login_response.status_code = 200
    mock_login_response.json.return_value = {"token": {"token": "FAKE_TOKEN_12345"}}
    mock_login_response.raise_for_status.return_value = None

    mocker.patch("mcp_network_jcd.tools.f5.requests.post", return_value=mock_login_response)

    mock_response = mocker.MagicMock()
    mock_response.status_code = 404
    mock_response.text = '{"code":404,"message":"Object not found"}'

    mocker.patch("mcp_network_jcd.tools.f5.requests.request", return_value=mock_response)
