"""Tests for dashboard store."""
import threading

import pytest

from ayn_antivirus.dashboard.store import DashboardStore


@pytest.fixture
def store(tmp_path):
    s = DashboardStore(str(tmp_path / "test_dashboard.db"))
    yield s
    s.close()


def test_record_and_get_metrics(store):
    store.record_metric(
        cpu=50.0, mem_pct=60.0, mem_used=4000, mem_total=8000,
        disk_usage=[{"mount": "/", "percent": 50}],
        load_avg=[1.0, 0.5, 0.3], net_conns=10,
    )
    latest = store.get_latest_metrics()
    assert latest is not None
    assert latest["cpu_percent"] == 50.0
    assert latest["mem_percent"] == 60.0
    assert latest["disk_usage"] == [{"mount": "/", "percent": 50}]
    assert latest["load_avg"] == [1.0, 0.5, 0.3]


def test_record_and_get_threats(store):
    store.record_threat(
        "/tmp/evil", "TestVirus", "malware", "HIGH",
        "test_det", "abc", "quarantined", "test detail",
    )
    threats = store.get_recent_threats(10)
    assert len(threats) == 1
    assert threats[0]["threat_name"] == "TestVirus"
    assert threats[0]["action_taken"] == "quarantined"


def test_threat_stats(store):
    store.record_threat("/a", "V1", "malware", "CRITICAL", "d", "", "detected", "")
    store.record_threat("/b", "V2", "miner", "HIGH", "d", "", "killed", "")
    store.record_threat("/c", "V3", "spyware", "MEDIUM", "d", "", "detected", "")
    stats = store.get_threat_stats()
    assert stats["total"] == 3
    assert stats["by_severity"]["CRITICAL"] == 1
    assert stats["by_severity"]["HIGH"] == 1
    assert stats["by_severity"]["MEDIUM"] == 1
    assert stats["last_24h"] == 3
    assert stats["last_7d"] == 3


def test_record_and_get_scans(store):
    store.record_scan("full", "/", 1000, 50, 2, 10.5)
    scans = store.get_recent_scans(10)
    assert len(scans) == 1
    assert scans[0]["files_scanned"] == 1000
    assert scans[0]["scan_type"] == "full"
    assert scans[0]["status"] == "completed"


def test_scan_chart_data(store):
    store.record_scan("full", "/", 100, 5, 1, 5.0)
    data = store.get_scan_chart_data(30)
    assert len(data) >= 1
    row = data[0]
    assert "day" in row
    assert "scans" in row
    assert "threats" in row


def test_sig_updates(store):
    store.record_sig_update("malwarebazaar", hashes=100, ips=50, domains=20, urls=10)
    updates = store.get_recent_sig_updates(10)
    assert len(updates) == 1
    assert updates[0]["feed_name"] == "malwarebazaar"
    stats = store.get_sig_stats()
    assert stats["total_hashes"] == 100
    assert stats["total_ips"] == 50
    assert stats["total_domains"] == 20
    assert stats["total_urls"] == 10


def test_activity_log(store):
    store.log_activity("Test message", "INFO", "test")
    logs = store.get_recent_logs(10)
    assert len(logs) == 1
    assert logs[0]["message"] == "Test message"
    assert logs[0]["level"] == "INFO"
    assert logs[0]["source"] == "test"


def test_metrics_history(store):
    store.record_metric(
        cpu=10, mem_pct=20, mem_used=1000, mem_total=8000,
        disk_usage=[], load_avg=[0.1], net_conns=5,
    )
    store.record_metric(
        cpu=20, mem_pct=30, mem_used=2000, mem_total=8000,
        disk_usage=[], load_avg=[0.2], net_conns=10,
    )
    history = store.get_metrics_history(hours=1)
    assert len(history) == 2
    assert history[0]["cpu_percent"] == 10
    assert history[1]["cpu_percent"] == 20


def test_cleanup_retains_fresh(store):
    """Cleanup with 0 hours should not delete just-inserted metrics."""
    store.record_metric(
        cpu=10, mem_pct=20, mem_used=1000, mem_total=8000,
        disk_usage=[], load_avg=[], net_conns=0,
    )
    store.cleanup_old_metrics(hours=0)
    assert store.get_latest_metrics() is not None


def test_empty_store_returns_none(store):
    """Empty store returns None / empty lists gracefully."""
    assert store.get_latest_metrics() is None
    assert store.get_recent_threats(10) == []
    assert store.get_recent_scans(10) == []
    assert store.get_recent_logs(10) == []
    stats = store.get_threat_stats()
    assert stats["total"] == 0


def test_thread_safety(store):
    """Concurrent writes from multiple threads should not crash."""
    errors = []

    def writer(n):
        try:
            for i in range(10):
                store.record_metric(
                    cpu=float(n * 10 + i), mem_pct=50, mem_used=4000,
                    mem_total=8000, disk_usage=[], load_avg=[], net_conns=0,
                )
        except Exception as e:
            errors.append(e)

    threads = [threading.Thread(target=writer, args=(i,)) for i in range(5)]
    for t in threads:
        t.start()
    for t in threads:
        t.join()
    assert len(errors) == 0
