import asyncio

from app.repositories import chunk_repo


class _FakeChunks:
    def __init__(self):
        self.docs = []

    async def create_index(self, keys, **kwargs):
        return None

    async def delete_many(self, query):
        remaining = []
        for doc in self.docs:
            if doc.get("repo_id") != query.get("repo_id"):
                remaining.append(doc)
                continue
            if doc.get("doc_path") != query.get("doc_path"):
                remaining.append(doc)
                continue
            if "$or" in query:
                snapshot_id = None
                for clause in query["$or"]:
                    if "snapshot_id" in clause:
                        snapshot_id = clause["snapshot_id"]
                if snapshot_id and doc.get("snapshot_id") != snapshot_id:
                    remaining.append(doc)
                    continue
            # matched delete
        self.docs = remaining


class _FakeDB:
    def __init__(self):
        self.doc_chunks = _FakeChunks()


def test_delete_chunks_for_doc_snapshot_only_removes_matching_snapshot(monkeypatch):
    fake_db = _FakeDB()
    monkeypatch.setattr(chunk_repo, "get_db", lambda: fake_db)
    monkeypatch.setattr(chunk_repo, "_INDEXES_READY", True)
    fake_db.doc_chunks.docs = [
        {"repo_id": "ad/repo", "doc_path": "README.md", "snapshot_id": "snap_a"},
        {"repo_id": "ad/repo", "doc_path": "README.md", "snapshot_id": "snap_b"},
    ]

    asyncio.run(
        chunk_repo.delete_chunks_for_doc_snapshot("ad/repo", "snap_a", "README.md")
    )

    assert len(fake_db.doc_chunks.docs) == 1
    assert fake_db.doc_chunks.docs[0]["snapshot_id"] == "snap_b"
