import os
import sqlite3
import tempfile
import unittest

from core.database import EventDatabase


class TestEventDatabase(unittest.TestCase):
    def test_database_builds_schema_and_writes_event(self):
        with tempfile.TemporaryDirectory() as tmpdir:
            db_path = os.path.join(tmpdir, "test_processmonitor.db")
            db = EventDatabase(db_path)

            try:
                event = {
                    "event_id": "evt-001",
                    "timestamp": "2026-08-13T12:00:00+00:00",
                    "event_type": "process_create",
                    "source": "kernel",
                    "severity": "info",
                    "confidence": 0,
                    "hostname": "WORKSTATION",
                    "user": "Joey",
                    "pid": 100,
                    "parent_pid": 1,
                    "process_name": "ollama.exe",
                    "path": r"C:\Program Files\Ollama\ollama.exe",
                    "command_line": "ollama serve",
                    "sha256": None,
                    "signer": None,
                    "signed": None,
                    "risk_score": 5,
                    "tags": ["ai", "watchlist"],
                    "metadata": {"origin": "kernel"},
                }

                db.insert_event(event)
                rows = db.list_events(limit=10)
                self.assertEqual(len(rows), 1)
                self.assertEqual(rows[0]["event_type"], "process_create")
                self.assertEqual(rows[0]["process_name"], "ollama.exe")

                alert = {
                    "alert_id": "alert-001",
                    "timestamp": "2026-08-13T12:00:01+00:00",
                    "severity": "medium",
                    "title": "Suspicious AI process",
                    "description": "Process launched from local AI runtime path",
                    "rule_id": "AI-001",
                    "status": "New",
                    "process_id": 100,
                    "event_id": "evt-001",
                    "analyst_notes": "Initial review",
                }

                db.insert_alert(alert)
                conn = sqlite3.connect(db_path)
                try:
                    count = conn.execute("SELECT COUNT(*) FROM alerts").fetchone()[0]
                    self.assertEqual(count, 1)
                finally:
                    conn.close()
                self.assertEqual("alert-001", db.list_alerts(10)[0]["alert_id"])
                metrics = db.get_dashboard_metrics()
                self.assertEqual(1, metrics["event_count"])
                self.assertEqual(1, metrics["alert_count"])
            finally:
                db.close()

    def test_schema_contains_expected_tables(self):
        with tempfile.TemporaryDirectory() as tmpdir:
            db_path = os.path.join(tmpdir, "schema_test.db")
            db = EventDatabase(db_path)
            try:
                expected_tables = {
                    "events",
                    "alerts",
                    "processes",
                    "rules",
                    "exclusions",
                    "audit_log",
                    "system_health",
                }
                conn = sqlite3.connect(db_path)
                try:
                    actual = {
                        row[0]
                        for row in conn.execute("SELECT name FROM sqlite_master WHERE type='table'")
                    }
                finally:
                    conn.close()
                self.assertTrue(expected_tables.issubset(actual))
            finally:
                db.close()

    def test_system_health_and_retention_management(self):
        with tempfile.TemporaryDirectory() as tmpdir:
            db_path = os.path.join(tmpdir, "retention_test.db")
            db = EventDatabase(db_path)
            try:
                db.insert_event({
                    "event_id": "old-event",
                    "timestamp": "2020-01-01T00:00:00+00:00",
                    "event_type": "process_create",
                    "source": "kernel",
                    "severity": "info",
                    "confidence": 0,
                    "hostname": "WORKSTATION",
                    "user": "system",
                    "pid": 42,
                    "parent_pid": 1,
                    "process_name": "legacy.exe",
                    "path": r"C:\Legacy\legacy.exe",
                    "command_line": "legacy.exe",
                    "sha256": None,
                    "signer": None,
                    "signed": None,
                    "risk_score": 0,
                    "tags": [],
                    "metadata": {},
                })
                db.insert_event({
                    "event_id": "new-event",
                    "timestamp": "2026-08-13T12:00:00+00:00",
                    "event_type": "process_create",
                    "source": "kernel",
                    "severity": "info",
                    "confidence": 0,
                    "hostname": "WORKSTATION",
                    "user": "system",
                    "pid": 43,
                    "parent_pid": 1,
                    "process_name": "active.exe",
                    "path": r"C:\Active\active.exe",
                    "command_line": "active.exe",
                    "sha256": None,
                    "signer": None,
                    "signed": None,
                    "risk_score": 0,
                    "tags": [],
                    "metadata": {},
                })
                db.insert_system_health("relay", "healthy", "Service running normally")
                pruned = db.prune_events(retention_days=30)
                self.assertEqual(pruned, 1)
                self.assertEqual(len(db.list_events(limit=10)), 1)
                self.assertEqual(db.list_system_health()[0]["component"], "relay")
            finally:
                db.close()


if __name__ == "__main__":
    unittest.main()
