#!/usr/bin/env python3
# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
"""
Graph SQLite Sync — writes knowledge graph to SQLite (Phase 4 unification).

SQLite is the single source of truth. JSON export kept for backward compat.
Preserves STDP/COACTIVATION edges (learned, not rebuilt by graph builder).
"""
import logging

log = logging.getLogger("pulse.graph.sqlite_sync")


def sync_to_sqlite(nodes: dict, edges: list, verbose: bool = False):
    """Write graph nodes and edges to SQLite as primary store."""
    try:
        from pulse.core.brain_db import get_conn
        conn = get_conn()
        with conn:
            # Clear existing graph data (preserve learned edges)
            conn.execute("DELETE FROM graph_nodes")
            conn.execute(
                "DELETE FROM graph_edges WHERE edge_type NOT IN ('TEMPORAL', 'COACTIVATION')"
            )

            # Insert nodes (domain from node dict, not source)
            for nid, node in nodes.items():
                conn.execute(
                    "INSERT OR REPLACE INTO graph_nodes "
                    "(id, type, text, confidence, domain) VALUES (?, ?, ?, ?, ?)",
                    (nid, node.get("type", "CONCEPT"),
                     (node.get("text", ""))[:200],
                     node.get("confidence", 0.5),
                     node.get("domain", "general"))
                )

            # Insert edges (OR IGNORE prevents UNIQUE crash that rolls back degree update)
            for edge in edges:
                conn.execute(
                    "INSERT OR IGNORE INTO graph_edges "
                    "(from_node, to_node, edge_type, confidence, source_node) "
                    "VALUES (?, ?, ?, ?, ?)",
                    (edge["from"], edge["to"], edge["type"],
                     edge.get("confidence", 0.5),
                     edge.get("source_node", ""))
                )

            # Insert stub nodes for TEMPORAL/COACTIVATION edge endpoints missing from graph_nodes
            preserved_edges = conn.execute(
                "SELECT DISTINCT from_node, to_node FROM graph_edges WHERE edge_type IN ('TEMPORAL', 'COACTIVATION')"
            ).fetchall()
            for row in preserved_edges:
                for endpoint in (row[0], row[1]):
                    if endpoint and not conn.execute(
                        "SELECT 1 FROM graph_nodes WHERE id = ?", (endpoint,)
                    ).fetchone():
                        conn.execute(
                            "INSERT OR IGNORE INTO graph_nodes (id, type, text, confidence, domain) VALUES (?, ?, ?, ?, ?)",
                            (endpoint, "CONCEPT", endpoint[:200], 0.3, "general")
                        )

            # Update degree counts
            conn.execute("""
                UPDATE graph_nodes SET degree = (
                    SELECT COUNT(*) FROM graph_edges
                    WHERE from_node = graph_nodes.id
                       OR to_node = graph_nodes.id
                )
            """)

        if verbose:
            print(f"  [GRAPH] SQLite synced: {len(nodes)} nodes, {len(edges)} edges")
    except Exception as e:
        if verbose:
            print(f"  [GRAPH] SQLite sync failed (JSON still written): {e}")
