"""
Tests for Wiring Sprint 3 — Miss.Bossy's 7 newly wired modules.
Verifies each module's functions return correct types and don't crash.
"""

import pytest
import sys
import os

sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src"))


# ── Compliance ───────────────────────────────────────────────────────────────

class TestCompliance:
    def test_get_compliance_report(self):
        from brynq.compliance import get_compliance_report
        result = get_compliance_report()
        assert isinstance(result, dict)

    def test_list_policies(self):
        from brynq.compliance import list_policies
        result = list_policies()
        assert isinstance(result, list)

    def test_get_audit_log(self):
        from brynq.compliance import get_audit_log
        result = get_audit_log()
        assert isinstance(result, (list, dict))

    def test_log_action(self):
        from brynq.compliance import log_action
        result = log_action("custom", details="test details")
        assert result is not None


# ── Onboarding ───────────────────────────────────────────────────────────────

class TestOnboarding:
    def test_get_onboarding_status(self):
        from brynq.onboarding import get_onboarding_status
        result = get_onboarding_status("test-agent-onboard")
        assert isinstance(result, dict)

    def test_get_knowledge(self):
        from brynq.onboarding import get_knowledge
        result = get_knowledge("test-topic")
        # Returns None if topic doesn't exist — that's correct behavior
        assert result is None or isinstance(result, (dict, str))

    def test_detect_new_agent(self):
        from brynq.onboarding import detect_new_agent
        result = detect_new_agent("test-new-agent")
        assert result is not None


# ── Retention ────────────────────────────────────────────────────────────────

class TestRetention:
    def test_get_stats(self):
        from brynq.retention import get_stats
        result = get_stats()
        assert isinstance(result, dict)

    def test_clean_stale_sessions(self):
        from brynq.retention import clean_stale_sessions
        result = clean_stale_sessions()
        assert result is not None


# ── Task Queue ───────────────────────────────────────────────────────────────

class TestTaskQueue:
    def test_get_queue_stats(self):
        from brynq.task_queue import get_queue_stats
        result = get_queue_stats()
        assert isinstance(result, dict)

    def test_enqueue_dequeue(self):
        import uuid
        from brynq.task_queue import enqueue, dequeue, get_queue_stats
        enqueue(f"test-task-queue-{uuid.uuid4().hex[:8]}", "normal")
        stats = get_queue_stats()
        assert isinstance(stats, dict)

    def test_get_overdue(self):
        from brynq.task_queue import get_overdue
        result = get_overdue()
        assert isinstance(result, (list, dict))

    def test_peek(self):
        from brynq.task_queue import peek
        result = peek()
        # Can be None if queue is empty, list, or dict
        assert result is None or isinstance(result, (dict, list))


# ── Task Templates ───────────────────────────────────────────────────────────

class TestTaskTemplates:
    def test_list_templates(self):
        from brynq.task_templates import list_templates
        result = list_templates()
        assert isinstance(result, list)

    def test_create_and_get_template(self):
        from brynq.task_templates import create_template, get_template, list_templates
        t = create_template(
            name="Test Template Sprint3",
            title_pattern="Test: {topic}",
            description_pattern="A test for {topic}",
            required_skills=["python"],
        )
        assert t is not None
        tid = t.get("template_id") or t.get("id", "")
        if tid:
            fetched = get_template(tid)
            assert fetched is not None

    def test_get_popular_templates(self):
        from brynq.task_templates import get_popular_templates
        result = get_popular_templates()
        assert isinstance(result, list)


# ── Template Marketplace ─────────────────────────────────────────────────────

class TestTemplateMarketplace:
    def test_browse_templates(self):
        from brynq.template_marketplace import browse_templates
        result = browse_templates()
        assert isinstance(result, list)

    def test_get_featured(self):
        from brynq.template_marketplace import get_featured
        result = get_featured()
        assert isinstance(result, list)

    def test_get_trending(self):
        from brynq.template_marketplace import get_trending
        result = get_trending()
        assert isinstance(result, list)


# ── Smart Routing ────────────────────────────────────────────────────────────

class TestSmartRouting:
    def test_get_routing_stats(self):
        from brynq.smart_routing import get_routing_stats
        result = get_routing_stats()
        assert isinstance(result, dict)

    def test_list_rules(self):
        from brynq.smart_routing import list_rules
        result = list_rules()
        assert isinstance(result, list)

    def test_get_least_loaded(self):
        from brynq.smart_routing import get_least_loaded
        result = get_least_loaded()
        # Can be None if no agents
        assert result is None or isinstance(result, (dict, str))

    def test_add_rule(self):
        from brynq.smart_routing import add_rule, list_rules
        add_rule(
            name="test-rule-sprint3",
            condition_fn=lambda task: "python" in task.get("skills", []),
            action="route_to_best",
        )
        rules = list_rules()
        assert isinstance(rules, list)
