# Tests for VendorBridge state persistence and recovery.
import sys
from pathlib import Path
from unittest.mock import patch, MagicMock

import pytest

# Add the example directory to the path to allow importing the bridge
example_dir = Path(__file__).resolve().parent.parent.parent / "sdk-examples" / "vendor-bridge"
sys.path.insert(0, str(example_dir))

from api_to_otlp_bridge import MockVendorBridge
from mca_sdk.config import MCAConfig

# Mock response for requests.get
mock_api_response = {
    "model_id": "vendor-model-123",
    "metrics": {
        "predictions_since_last_poll": 10,
        "errors_since_last_poll": 1,
        "accuracy": 0.91,
        "f1_score": 0.88,
        "avg_latency_ms": 75.0,
    },
    "timestamp": "2026-02-14T12:00:00Z",
}


@pytest.fixture
def mock_requests_get():
    """Fixture to mock requests.get for the vendor bridge."""
    with patch("requests.get") as mock_get:
        mock_response = MagicMock()
        mock_response.status_code = 200
        mock_response.json.return_value = mock_api_response
        mock_get.return_value = mock_response
        yield mock_get


@pytest.fixture
def mock_mca_client():
    """Fixture to mock the MCAClient."""
    with patch("mca_sdk.integrations.bridge.MCAClient") as mock_client_class:
        mock_client = MagicMock()
        mock_client_class.return_value = mock_client
        yield mock_client


class TestVendorBridgeStatePersistence:
    """Validates that the VendorBridge correctly persists and recovers state."""

    def test_state_is_persisted_and_recovered(self, tmp_path, mock_requests_get, mock_mca_client):
        """
        Tests that cumulative counters are saved to a state file and recovered
        on subsequent bridge initializations.
        """
        state_file = tmp_path / "vendor_bridge_state.db"

        # --- First run ---
        print(f"\n--- First Run: Initializing bridge, state file at {state_file} ---")
        config1 = MCAConfig(
            service_name="test-service",
            vendor_api_url="http://mock-vendor.com/api",
            collector_endpoint="http://localhost:4318",
            vendor_bridge_state_file=str(state_file),
            vendor_bridge_max_iterations=2,  # Run for 2 cycles
            allow_insecure_collector=True,
        )
        bridge1 = MockVendorBridge(config1)

        bridge1.start()
        bridge1.wait_for_completion()
        bridge1.close()

        stats1 = bridge1.get_stats()
        print(f"Run 1 stats: {stats1}")
        assert stats1["success_count"] == 2
        # After 2 polls (10 each), total should be 20
        assert bridge1._cumulative_predictions == 20
        assert bridge1._cumulative_errors == 2

        # --- Second run ---
        print("\n--- Second Run: Initializing new bridge from same state file ---")

        # Update mock data for the second run to see increment
        mock_api_response["metrics"]["predictions_since_last_poll"] = 5
        mock_api_response["metrics"]["errors_since_last_poll"] = 2
        mock_requests_get.return_value.json.return_value = mock_api_response

        config2 = MCAConfig(
            service_name="test-service",
            vendor_api_url="http://mock-vendor.com/api",
            collector_endpoint="http://localhost:4318",
            vendor_bridge_state_file=str(state_file),
            vendor_bridge_max_iterations=1,  # Run for 1 cycle
            allow_insecure_collector=True,
        )
        bridge2 = MockVendorBridge(config2)

        # Verify state was loaded correctly
        print(
            f"Bridge 2 initial state: predictions={bridge2._cumulative_predictions}, errors={bridge2._cumulative_errors}"
        )
        assert bridge2._cumulative_predictions == 20  # Should load from state
        assert bridge2._cumulative_errors == 2

        bridge2.start()
        bridge2.wait_for_completion()
        bridge2.close()

        stats2 = bridge2.get_stats()
        print(f"Run 2 stats: {stats2}")
        assert stats2["success_count"] == 1
        # Should be 20 (loaded) + 5 (new) = 25
        assert bridge2._cumulative_predictions == 25
        # Should be 2 (loaded) + 2 (new) = 4
        assert bridge2._cumulative_errors == 4
        print("\nState persistence and recovery test passed.")
