from __future__ import annotations

import csv
import io
import os
from dataclasses import dataclass, field
from pathlib import Path
from typing import Any, Dict, Iterable, List, Optional

from core.database import EventDatabase
from core.event_model import NormalizedEvent


@dataclass
class ProcessTelemetryCollector:
    """Collects tasklist snapshots and normalizes them into the shared event model."""

    db_path: Optional[str | os.PathLike[str]] = None
    database: Optional[EventDatabase] = field(default=None, init=False)

    def __post_init__(self):
        self.database = EventDatabase(self.db_path) if self.db_path is not None else EventDatabase()

    def parse_tasklist_csv(self, csv_text: str) -> List[NormalizedEvent]:
        rows: List[NormalizedEvent] = []
        reader = csv.DictReader(io.StringIO(csv_text.strip()))
        for raw in reader:
            if not raw:
                continue
            image_name = (raw.get("Image Name") or raw.get("image") or "").strip()
            pid_value = raw.get("PID") or raw.get("pid") or ""
            try:
                pid = int(str(pid_value).replace(",", "").strip())
            except (TypeError, ValueError):
                continue

            event = NormalizedEvent(
                event_type="process_snapshot",
                source="tasklist",
                severity="info",
                confidence=0,
                pid=pid,
                process_name=image_name,
                path=None,
                command_line="",
                metadata={
                    "session_name": raw.get("Session Name"),
                    "session_id": raw.get("Session#"),
                    "mem_usage": raw.get("Mem Usage"),
                },
            )
            rows.append(event)
        return rows

    def collect_once(self, csv_text: Optional[str] = None) -> List[NormalizedEvent]:
        if csv_text is None:
            raise ValueError("csv_text is required for a snapshot collection pass")

        events = self.parse_tasklist_csv(csv_text)
        for event in events:
            payload = event.to_dict()
            self.database.insert_event(payload)
        return events

    def list_recent_events(self, limit: int = 25) -> List[Dict[str, Any]]:
        return self.database.list_events(limit=limit)

    def close(self) -> None:
        if self.database is not None:
            self.database.close()
