"""
xmldev.audit
~~~~~~~~~~~~
Patch record dataclass and audit JSON writer.
"""
from __future__ import annotations

import json
import uuid
from dataclasses import asdict, dataclass, field
from datetime import datetime, timezone
from pathlib import Path
from typing import Any


# ---------------------------------------------------------------------------
# Patch record
# ---------------------------------------------------------------------------

@dataclass
class Patch:
    """A single change record produced by the repair pipeline."""

    id: str = field(default_factory=lambda: str(uuid.uuid4()))
    type: str = ""           # rename | insert | delete | coerce | reorder | move
    path: str = ""           # XPath-like: /person[1]/name[1]
    original: str = ""       # original XML fragment or value
    replacement: str = ""    # replacement XML fragment or value
    rule_id: str = ""        # e.g. "fuzzy_rename_v1"
    confidence: float = 1.0  # 0.0 – 1.0
    auto_applied: bool = False
    timestamp: str = field(default_factory=lambda: datetime.now(timezone.utc).isoformat())
    source: str = "deterministic"   # deterministic | heuristic | llm
    notes: str = ""

    def to_dict(self) -> dict[str, Any]:
        return asdict(self)


# ---------------------------------------------------------------------------
# Audit writer
# ---------------------------------------------------------------------------

class AuditWriter:
    """Serialises a list of patches to an audit JSON file."""

    @staticmethod
    def build_summary(patches: list[Patch]) -> dict[str, Any]:
        total = len(patches)
        by_type: dict[str, int] = {}
        by_source: dict[str, int] = {}
        auto_applied = 0

        for p in patches:
            by_type[p.type] = by_type.get(p.type, 0) + 1
            by_source[p.source] = by_source.get(p.source, 0) + 1
            if p.auto_applied:
                auto_applied += 1

        return {
            "total_patches": total,
            "auto_applied": auto_applied,
            "pending_review": total - auto_applied,
            "by_type": by_type,
            "by_source": by_source,
        }

    @classmethod
    def write(cls, patches: list[Patch], path: str | Path) -> None:
        """Write patches + summary to a JSON file."""
        audit = {
            "summary": cls.build_summary(patches),
            "patches": [p.to_dict() for p in patches],
        }
        Path(path).write_text(json.dumps(audit, indent=2), encoding="utf-8")

    @staticmethod
    def to_dict(patches: list[Patch]) -> dict[str, Any]:
        """Return the audit dict without writing to disk."""
        return {
            "summary": AuditWriter.build_summary(patches),
            "patches": [p.to_dict() for p in patches],
        }
