"""Phase 3: Embedding Vector Poisoning.

Replaces all embedding vectors with random noise before deletion.
Ensures no semantic information can be reconstructed from vector residue,
even if SQLite WAL or journal files retain fragments.
"""

import os
import json
import logging
from soagila.db.sqlite_init import get_db

logger = logging.getLogger("soagila.sdijap.embedding_poisoner")

EMBEDDING_DIM = 384  # all-MiniLM-L6-v2 dimension


def _random_embedding() -> str:
    """Generate a random noise vector as JSON string."""
    # Use os.urandom for cryptographic randomness, convert to floats in [-1, 1]
    raw = os.urandom(EMBEDDING_DIM * 4)
    floats = []
    for i in range(EMBEDDING_DIM):
        byte_val = raw[i * 4]  # Use one byte per dimension
        floats.append((byte_val / 128.0) - 1.0)  # Map [0,255] to [-1, 1]
    return json.dumps(floats)


async def poison_all_embeddings() -> int:
    """Replace all embedding vectors with random noise.

    This runs BEFORE data deletion to ensure WAL/journal residue
    contains only noise, not real semantic vectors.

    Returns count of poisoned embeddings.
    """
    db = await get_db()
    count = 0

    # Poison episodic embeddings
    cursor = await db.execute(
        "SELECT id FROM episodic_memories WHERE embedding IS NOT NULL"
    )
    rows = await cursor.fetchall()
    for row in rows:
        noise = _random_embedding()
        await db.execute(
            "UPDATE episodic_memories SET embedding = ? WHERE id = ?",
            (noise, row[0]),
        )
        count += 1

    # Poison semantic embeddings
    cursor = await db.execute(
        "SELECT id FROM semantic_memories WHERE embedding IS NOT NULL"
    )
    rows = await cursor.fetchall()
    for row in rows:
        noise = _random_embedding()
        await db.execute(
            "UPDATE semantic_memories SET embedding = ? WHERE id = ?",
            (noise, row[0]),
        )
        count += 1

    await db.commit()

    logger.info(f"Phase 3 complete: {count} embeddings poisoned with random noise")
    return count
