"""CRUD over ``memory_records`` + ``memory_branch_summaries``.

Persistence emits ``memory_snapshot_landed`` audit event tied to the
new memory_root. Branch summaries are written one row per branch,
content-addressed by ``branch_digest``.
"""

from __future__ import annotations

import sqlite3
import time
from typing import Iterable, Optional

from arborist.memory.canonical import (
    BranchSummary,
    MemorySnapshot,
    branch_digest,
    canonical_branches_blob,
    memory_root,
)
from arborist.store import append_audit


def store_snapshot(
    conn: sqlite3.Connection,
    snapshot: MemorySnapshot,
    *,
    ts: Optional[int] = None,
) -> str:
    """Persist a memory snapshot + its branch summaries; return memory_root.

    Idempotent on (memory_root): re-storing the same snapshot is a no-op.
    """
    root = memory_root(snapshot)
    body_blob = canonical_branches_blob(snapshot).encode(
        "utf-8", errors="surrogatepass"
    )
    if ts is None:
        ts = int(time.time())

    existing = conn.execute(
        "SELECT 1 FROM memory_records WHERE memory_root = ?", (root,)
    ).fetchone()
    if existing is not None:
        return root

    event_hash = append_audit(
        conn,
        event_type="memory_snapshot_landed",
        subject_root=root,
        body={
            "memory_root": root,
            "schema_version": snapshot.schema_version,
            "parent_memory_root": snapshot.parent_memory_root,
            "branch_count": len(snapshot.branches),
            "audit_events_high_water": snapshot.audit_events_high_water,
        },
        ts=ts,
    )

    conn.execute(
        "INSERT INTO memory_records ("
        " memory_root, schema_version, parent_memory_root,"
        " audit_events_high_water, branch_summaries_blob,"
        " state, audit_event_hash, created_at"
        ") VALUES (?, ?, ?, ?, ?, 'live', ?, ?)",
        (
            root,
            snapshot.schema_version,
            snapshot.parent_memory_root,
            snapshot.audit_events_high_water,
            body_blob,
            event_hash,
            ts,
        ),
    )

    for branch in snapshot.branches:
        digest = branch_digest(branch)
        conn.execute(
            "INSERT OR IGNORE INTO memory_branch_summaries ("
            " branch_id, memory_root, summary_digest, summary_blob, count"
            ") VALUES (?, ?, ?, ?, ?)",
            (
                branch.branch_id,
                root,
                digest,
                branch.summary_blob,
                int(branch.count),
            ),
        )

    return root


def load(conn: sqlite3.Connection, root: str) -> Optional[dict]:
    row = conn.execute(
        "SELECT memory_root, schema_version, parent_memory_root,"
        "       audit_events_high_water, branch_summaries_blob,"
        "       state, audit_event_hash, created_at,"
        "       falsified_at, falsified_reason"
        " FROM memory_records WHERE memory_root = ?",
        (root,),
    ).fetchone()
    if row is None:
        return None
    return dict(row)


def latest(conn: sqlite3.Connection) -> Optional[dict]:
    row = conn.execute(
        "SELECT memory_root, schema_version, parent_memory_root,"
        "       audit_events_high_water, branch_summaries_blob,"
        "       state, audit_event_hash, created_at,"
        "       falsified_at, falsified_reason"
        " FROM memory_records "
        " WHERE state = 'live' "
        " ORDER BY created_at DESC LIMIT 1"
    ).fetchone()
    if row is None:
        return None
    return dict(row)


def branches_for(conn: sqlite3.Connection, root: str) -> list[dict]:
    """Return all branch summaries attached to a memory_root."""
    rows = conn.execute(
        "SELECT branch_id, memory_root, summary_digest, summary_blob, count"
        " FROM memory_branch_summaries"
        " WHERE memory_root = ?"
        " ORDER BY branch_id",
        (root,),
    ).fetchall()
    return [dict(r) for r in rows]
