"""Auto-migrate ChromaDB data to the new vector backend.

On startup, if store_backend=local and ChromaDB data exists at ~/.sulci/chroma/,
this module reads all embeddings from ChromaDB and writes them to the new backend,
then renames chroma/ → chroma.bak/.
"""

import logging
from pathlib import Path

logger = logging.getLogger(__name__)


async def migrate_chroma_to_backend(chroma_path: Path, vector_backend) -> int:
    """Migrate ChromaDB vectors to the given vector backend.

    Args:
        chroma_path: Path to the ChromaDB persistent storage directory.
        vector_backend: An initialized VectorBackend instance.

    Returns:
        Number of vectors migrated.
    """
    if not chroma_path.exists():
        return 0

    # Check for actual ChromaDB data (not just an empty directory)
    chroma_files = list(chroma_path.glob("*"))
    if not chroma_files or (len(chroma_files) == 1 and chroma_files[0].name == ".gitkeep"):
        return 0

    try:
        import chromadb
    except ImportError:
        logger.info("chromadb not installed — skipping migration (install with: pip install chromadb)")
        return 0

    logger.info("Found ChromaDB data at %s — starting migration", chroma_path)

    try:
        client = chromadb.PersistentClient(path=str(chroma_path))
        collection = client.get_or_create_collection(
            name="knowledge_atoms",
            metadata={"hnsw:space": "cosine"},
        )
        count = collection.count()
        if count == 0:
            logger.info("ChromaDB collection is empty — nothing to migrate")
            _backup_chroma_dir(chroma_path)
            return 0

        # Read all data from ChromaDB
        data = collection.get(include=["embeddings", "documents", "metadatas"], limit=count)
        ids = data.get("ids") or []
        embeddings = data.get("embeddings")
        documents = data.get("documents") or []
        metadatas = data.get("metadatas") or []

        # ChromaDB may return numpy arrays — use len() instead of truthiness
        if not ids or embeddings is None or len(embeddings) == 0:
            logger.info("No embeddings found in ChromaDB — nothing to migrate")
            _backup_chroma_dir(chroma_path)
            return 0

        # Build batch items — convert numpy arrays to plain lists
        items = []
        for i, atom_id in enumerate(ids):
            emb = embeddings[i] if i < len(embeddings) else None
            doc = documents[i] if i < len(documents) else ""
            meta = metadatas[i] if i < len(metadatas) else {}
            if emb is not None:
                emb_list = list(emb) if not isinstance(emb, list) else emb
                items.append((atom_id, emb_list, meta or {}, doc or ""))

        # Write to new backend
        await vector_backend.upsert_batch(items)

        _backup_chroma_dir(chroma_path)
        logger.info("Migrated %d vectors from ChromaDB to new backend", len(items))
        return len(items)

    except Exception as e:
        logger.error("ChromaDB migration failed: %s — ChromaDB data left intact", e)
        return 0


def _backup_chroma_dir(chroma_path: Path) -> None:
    """Rename chroma/ → chroma.bak/ to signal migration is complete."""
    backup_path = chroma_path.parent / "chroma.bak"
    if backup_path.exists():
        import shutil

        shutil.rmtree(backup_path)
    chroma_path.rename(backup_path)
    logger.info("Backed up ChromaDB data to %s", backup_path)
