"""
Tests for insaits/readiness.py - System self-validation
"""

import pytest
from unittest.mock import MagicMock, patch
from insa_its.readiness import ReadinessChecker


def _make_mock_monitor(tier="free", is_validated=True, api_key="test"):
    """Create a mock monitor with configurable properties."""
    monitor = MagicMock()
    monitor.license = MagicMock()
    monitor.license.tier = tier
    monitor.license.is_validated = is_validated
    monitor.license.api_key = api_key
    monitor.detector = MagicMock()
    monitor.detector._premium_detector = None
    monitor.detector._adaptive_dict = None
    monitor.detector._detect_anchor_drift = None
    return monitor


class TestReadinessChecker:
    def test_check_returns_dict(self):
        monitor = _make_mock_monitor()
        checker = ReadinessChecker(monitor)
        result = checker.check()

        assert isinstance(result, dict)
        assert "ready" in result
        assert "checks" in result
        assert "warnings" in result
        assert "errors" in result
        assert "timestamp" in result

    def test_check_has_all_subsystems(self):
        monitor = _make_mock_monitor()
        checker = ReadinessChecker(monitor)
        result = checker.check()

        expected_checks = {
            "license", "embeddings_local", "ollama",
            "cloud", "anomaly_engine", "storage",
        }
        assert set(result["checks"].keys()) == expected_checks

    def test_each_check_has_status(self):
        monitor = _make_mock_monitor()
        checker = ReadinessChecker(monitor)
        result = checker.check()

        for name, check in result["checks"].items():
            assert "status" in check, f"Check '{name}' missing status"
            assert "detail" in check, f"Check '{name}' missing detail"
            assert check["status"] in ("ok", "warn", "fail"), (
                f"Check '{name}' has invalid status: {check['status']}"
            )


class TestLicenseCheck:
    def test_validated_key(self):
        monitor = _make_mock_monitor(tier="lifetime", is_validated=True)
        checker = ReadinessChecker(monitor)
        result = checker.check()
        assert result["checks"]["license"]["status"] == "ok"
        assert "lifetime" in result["checks"]["license"]["detail"]

    def test_no_api_key(self):
        monitor = _make_mock_monitor(api_key=None)
        checker = ReadinessChecker(monitor)
        result = checker.check()
        assert result["checks"]["license"]["status"] == "warn"
        assert "anonymous" in result["checks"]["license"]["detail"].lower() or \
               "No API key" in result["checks"]["license"]["detail"]

    def test_unvalidated_key(self):
        monitor = _make_mock_monitor(is_validated=False)
        checker = ReadinessChecker(monitor)
        result = checker.check()
        assert result["checks"]["license"]["status"] == "warn"

    def test_missing_license_manager(self):
        monitor = MagicMock()
        monitor.license = None
        monitor.detector = MagicMock()
        checker = ReadinessChecker(monitor)
        result = checker.check()
        assert result["checks"]["license"]["status"] == "fail"


class TestAnomalyEngineCheck:
    def test_detector_ok(self):
        monitor = _make_mock_monitor()
        checker = ReadinessChecker(monitor)
        result = checker.check()
        assert result["checks"]["anomaly_engine"]["status"] == "ok"
        assert "fingerprint_mismatch" in result["checks"]["anomaly_engine"]["detail"]

    def test_detector_with_premium(self):
        monitor = _make_mock_monitor()
        monitor.detector._premium_detector = MagicMock()
        monitor.detector._adaptive_dict = MagicMock()
        checker = ReadinessChecker(monitor)
        result = checker.check()
        detail = result["checks"]["anomaly_engine"]["detail"]
        assert "premium_detection" in detail
        assert "adaptive_dictionary" in detail

    def test_missing_detector(self):
        monitor = MagicMock()
        monitor.license = MagicMock()
        monitor.license.tier = "free"
        monitor.license.is_validated = True
        monitor.license.api_key = "test"
        monitor.detector = None
        checker = ReadinessChecker(monitor)
        result = checker.check()
        assert result["checks"]["anomaly_engine"]["status"] == "fail"


class TestEmbeddingsCheck:
    @patch("insa_its.readiness.ReadinessChecker._check_local_embeddings")
    def test_model_available(self, mock_check):
        mock_check.return_value = {
            "status": "ok",
            "detail": "sentence-transformers loaded",
            "critical": False,
        }
        monitor = _make_mock_monitor()
        checker = ReadinessChecker(monitor)
        result = checker.check()
        assert result["checks"]["embeddings_local"]["status"] == "ok"


class TestReadyFlag:
    def test_ready_when_all_critical_pass(self):
        monitor = _make_mock_monitor()
        checker = ReadinessChecker(monitor)
        result = checker.check()
        # Should be ready (license=ok/warn, embeddings=ok/warn, anomaly=ok, storage=ok)
        assert result["ready"] is True
        assert len(result["errors"]) == 0

    def test_not_ready_on_critical_failure(self):
        monitor = MagicMock()
        monitor.license = None  # Will cause fail with critical=True
        monitor.detector = MagicMock()
        checker = ReadinessChecker(monitor)
        result = checker.check()
        assert result["ready"] is False
        assert len(result["errors"]) > 0
