"""Audit trail: structured log of autonomous agent actions.

Never logs vault content or PII. Records: timestamp, action type,
target (file path or domain), proactivity level, approval status.
"""

from __future__ import annotations

import json
import logging
from datetime import UTC, datetime
from pathlib import Path

log = logging.getLogger(__name__)


class AuditTrail:
    """Append-only structured audit log for agent actions."""

    def __init__(self, log_path: Path) -> None:
        self._path = log_path
        self._path.parent.mkdir(parents=True, exist_ok=True)

    def log_action(
        self,
        action: str,
        target: str = "",
        proactivity: str = "",
        approved: str = "auto",
        metadata: dict | None = None,
    ) -> None:
        """Log an autonomous action."""
        entry = {
            "ts": datetime.now(UTC).isoformat(),
            "action": action,
            "target": target,
            "proactivity": proactivity,
            "approved": approved,
        }
        if metadata:
            entry["meta"] = metadata

        line = json.dumps(entry, separators=(",", ":"))
        with open(self._path, "a", encoding="utf-8") as f:
            f.write(line + "\n")

    def get_entries(
        self,
        limit: int = 50,
        action_filter: str | None = None,
        date_filter: str | None = None,
    ) -> list[dict]:
        """Read recent audit entries.

        Args:
            limit: Max entries to return.
            action_filter: Filter by action type.
            date_filter: Filter by date (YYYY-MM-DD prefix match).
        """
        if not self._path.exists():
            return []

        entries = []
        with open(self._path, encoding="utf-8") as f:
            for line in f:
                line = line.strip()
                if not line:
                    continue
                try:
                    entry = json.loads(line)
                except json.JSONDecodeError:
                    continue

                if action_filter and entry.get("action") != action_filter:
                    continue
                if date_filter and not entry.get("ts", "").startswith(date_filter):
                    continue

                entries.append(entry)

        # Return most recent first
        entries.reverse()
        return entries[:limit]

    def get_today(self) -> list[dict]:
        """Get all entries from today."""
        today = datetime.now(UTC).strftime("%Y-%m-%d")
        return self.get_entries(limit=200, date_filter=today)

    def purge(self, before_date: str | None = None) -> int:
        """Purge audit entries. Returns count removed.

        Args:
            before_date: Remove entries before this date (YYYY-MM-DD).
                         If None, purges all entries.
        """
        if not self._path.exists():
            return 0

        if before_date is None:
            count = len(self.get_entries(limit=999999))
            self._path.write_text("", encoding="utf-8")
            return count

        kept = []
        removed = 0
        with open(self._path, encoding="utf-8") as f:
            for line in f:
                line = line.strip()
                if not line:
                    continue
                try:
                    entry = json.loads(line)
                    if entry.get("ts", "")[:10] < before_date:
                        removed += 1
                    else:
                        kept.append(line)
                except json.JSONDecodeError:
                    kept.append(line)

        self._path.write_text("\n".join(kept) + ("\n" if kept else ""), encoding="utf-8")
        return removed
