"""Tests for BehavioralFingerprintDetector (Priority #2, OWASP MCP04)."""

import pytest
from insa_its.detectors.behavioral_fingerprint import BehavioralFingerprintDetector


class TestInit:
    def test_creates_detector(self):
        d = BehavioralFingerprintDetector()
        assert d.name == "behavioral_fingerprint"
        assert d.enabled is True

    def test_no_fingerprints_initially(self):
        d = BehavioralFingerprintDetector()
        assert len(d._fingerprints) == 0


class TestWarmup:
    def test_warmup_phase(self):
        d = BehavioralFingerprintDetector()
        result = d.check("Hello world", 1, agent_id="agent_a")
        assert result["detected"] is False
        assert result["evidence"].get("warmup") is True

    def test_warmup_completes_after_window(self):
        d = BehavioralFingerprintDetector()
        for i in range(d.WARMUP_WINDOW):
            result = d.check(f"Normal message number {i} with some content", i + 1, agent_id="agent_a")
        # After warmup, warmup should not be in evidence
        assert result["evidence"].get("warmup") is not True or result["evidence"].get("messages_until_ready") == 0


class TestBehavioralChange:
    def _warmup_agent(self, d, agent_id="agent_a"):
        """Feed normal messages to establish baseline."""
        normal_msgs = [
            "The quarterly report shows revenue of $2.4 million.",
            "Our analysis indicates a 15% growth rate this quarter.",
            "The customer satisfaction scores improved by 8 points.",
            "We processed 1,200 orders in the last 30 days.",
            "The average response time decreased to 2.3 seconds.",
            "Marketing campaign reached 50,000 unique visitors.",
            "Team productivity increased by 12% after the reorganization.",
            "The new feature rollout affected 30% of the user base.",
            "Bug reports decreased by 25% since the last patch.",
            "Server uptime maintained at 99.97% this month.",
        ]
        for i, msg in enumerate(normal_msgs):
            d.check(msg, i + 1, agent_id=agent_id)

    def test_detects_message_length_anomaly(self):
        d = BehavioralFingerprintDetector()
        self._warmup_agent(d)
        # Send a very short message (anomalous compared to baseline)
        result = d.check("ok", 11, agent_id="agent_a")
        # Should flag the length anomaly
        if result["detected"]:
            assert "message_length_anomaly" in result["flags"]

    def test_detects_new_capability(self):
        d = BehavioralFingerprintDetector()
        self._warmup_agent(d)
        # Suddenly start using SQL (not in baseline)
        result = d.check(
            "SELECT * FROM users WHERE role = 'admin'; DROP TABLE sessions;",
            11, agent_id="agent_a",
        )
        if result["detected"]:
            assert "new_capability_detected" in result["flags"]

    def test_stable_behavior_no_detection(self):
        d = BehavioralFingerprintDetector()
        self._warmup_agent(d)
        result = d.check(
            "The monthly report shows steady performance metrics across all departments.",
            11, agent_id="agent_a",
        )
        # Normal message similar to baseline should not trigger
        assert result["detected"] is False or "new_capability_detected" not in result.get("flags", [])


class TestSnapshot:
    def test_take_snapshot(self):
        d = BehavioralFingerprintDetector()
        # Need baseline first
        for i in range(d.WARMUP_WINDOW):
            d.check(f"Normal message content number {i}", i + 1, agent_id="bot")
        result = d.take_snapshot("bot")
        assert result["snapshot"] is True

    def test_snapshot_fails_without_baseline(self):
        d = BehavioralFingerprintDetector()
        result = d.take_snapshot("nonexistent")
        assert result["snapshot"] is False

    def test_snapshot_fails_during_warmup(self):
        d = BehavioralFingerprintDetector()
        d.check("Hello", 1, agent_id="bot")
        result = d.take_snapshot("bot")
        assert result["snapshot"] is False


class TestPerAgentTracking:
    def test_independent_agent_fingerprints(self):
        d = BehavioralFingerprintDetector()
        d.check("Hello from agent A", 1, agent_id="agent_a")
        d.check("Hello from agent B", 2, agent_id="agent_b")
        assert "agent_a" in d._fingerprints
        assert "agent_b" in d._fingerprints
        assert d._fingerprints["agent_a"]["message_count"] == 1
        assert d._fingerprints["agent_b"]["message_count"] == 1


class TestReset:
    def test_reset_clears_all(self):
        d = BehavioralFingerprintDetector()
        d.check("msg", 1, agent_id="a")
        d.reset()
        assert len(d._fingerprints) == 0
        assert len(d._snapshots) == 0

    def test_reset_agent(self):
        d = BehavioralFingerprintDetector()
        d.check("msg", 1, agent_id="a")
        d.check("msg", 2, agent_id="b")
        d.reset_agent("a")
        assert "a" not in d._fingerprints
        assert "b" in d._fingerprints


class TestResultFormat:
    def test_result_has_required_fields(self):
        d = BehavioralFingerprintDetector()
        result = d.check("Test message", 1, agent_id="test")
        assert "detected" in result
        assert "anomaly_type" in result
        assert "severity" in result
        assert "flags" in result
        assert "evidence" in result
        assert "timestamp_us" in result
        assert result["anomaly_type"] == "BEHAVIORAL_FINGERPRINT_CHANGE"
