"""
Tests for CascadeHelper.delete_document_completely() deletion order.

Verifies that deletion happens in the correct order:
1. DocumentBlob
2. DocumentCollection links
3. Document itself
"""

from unittest.mock import MagicMock

from local_deep_research.research_library.deletion.utils.cascade_helper import (
    CascadeHelper,
)


def _make_session(blob_deleted=1, collection_deleted=1, doc_deleted=1):
    """Build a mock session with configurable delete return values."""
    session = MagicMock()

    # Track call order
    call_order = []

    def make_query_chain(model_class, delete_return):
        chain = MagicMock()
        chain.filter_by.return_value = chain
        chain.delete.side_effect = lambda **kw: (
            call_order.append(model_class.__name__),
            delete_return,
        )[1]
        return chain

    from local_deep_research.database.models.library import (
        Document,
        DocumentBlob,
        DocumentCollection,
    )

    query_map = {
        DocumentBlob: make_query_chain(DocumentBlob, blob_deleted),
        DocumentCollection: make_query_chain(
            DocumentCollection, collection_deleted
        ),
        Document: make_query_chain(Document, doc_deleted),
    }

    session.query.side_effect = lambda model: query_map[model]
    session._call_order = call_order
    return session


class TestDeletionOrder:
    """Verify deletion order: Blob → Collection → Document."""

    def test_deletion_order_blob_before_collection_before_document(self):
        """DocumentBlob deleted BEFORE DocumentCollection BEFORE Document."""
        session = _make_session()
        CascadeHelper.delete_document_completely(session, "doc-123")
        assert session._call_order == [
            "DocumentBlob",
            "DocumentCollection",
            "Document",
        ]

    def test_document_exists_returns_true(self):
        """Document deleted (1 row) → returns True."""
        session = _make_session(doc_deleted=1)
        result = CascadeHelper.delete_document_completely(session, "doc-123")
        assert result is True

    def test_document_not_exists_returns_false(self):
        """Document not found (0 rows deleted) → returns False."""
        session = _make_session(doc_deleted=0)
        result = CascadeHelper.delete_document_completely(session, "doc-123")
        assert result is False

    def test_no_blob_still_returns_true(self):
        """No blob exists but document exists → still True."""
        session = _make_session(blob_deleted=0, doc_deleted=1)
        result = CascadeHelper.delete_document_completely(session, "doc-123")
        assert result is True

    def test_synchronize_session_false_used(self):
        """synchronize_session=False used for all delete calls."""
        session = _make_session()
        CascadeHelper.delete_document_completely(session, "doc-123")

        from local_deep_research.database.models.library import (
            Document,
            DocumentBlob,
            DocumentCollection,
        )

        for model in [DocumentBlob, DocumentCollection, Document]:
            chain = session.query(model)
            chain.filter_by.return_value.delete.assert_called_with(
                synchronize_session=False
            )

    def test_multiple_collection_links_all_deleted(self):
        """Multiple collection links → all deleted in one call."""
        session = _make_session(collection_deleted=5)
        result = CascadeHelper.delete_document_completely(session, "doc-123")
        assert result is True
        # Verify collection delete was called
        assert "DocumentCollection" in session._call_order

    def test_session_query_called_with_correct_models(self):
        """Session.query called with DocumentBlob, DocumentCollection, Document."""
        session = _make_session()
        CascadeHelper.delete_document_completely(session, "doc-123")

        from local_deep_research.database.models.library import (
            Document,
            DocumentBlob,
            DocumentCollection,
        )

        called_models = [c.args[0] for c in session.query.call_args_list]
        assert called_models == [DocumentBlob, DocumentCollection, Document]

    def test_filter_by_uses_document_id(self):
        """All filter_by calls use the provided document_id."""
        session = _make_session()
        CascadeHelper.delete_document_completely(session, "abc-456")

        from local_deep_research.database.models.library import (
            Document,
            DocumentBlob,
            DocumentCollection,
        )

        for model in [DocumentBlob, DocumentCollection]:
            chain = session.query(model)
            chain.filter_by.assert_called_with(document_id="abc-456")

        doc_chain = session.query(Document)
        doc_chain.filter_by.assert_called_with(id="abc-456")
