"""
Utility helpers for the library app.
"""

import logging

logger = logging.getLogger(__name__)


def neo4j_available():
    """
    Check whether Neo4j is reachable.

    Returns True if a simple Cypher query succeeds, False otherwise.
    Used to guard views/tests that require Neo4j.
    """
    try:
        from neomodel import db

        db.cypher_query("RETURN 1")
        return True
    except Exception:
        return False


def library_uids_for_user(username: str) -> set[str]:
    """Return the UIDs of every Library this user may read on the REST surface.

    A Library is visible to ``username`` if it has no ``owner_username``
    (global / shared) or its ``owner_username`` matches. Used by the
    ingest job endpoints to filter rows to the calling user's
    workspaces — mirrors the owner-scoping on
    ``/library/api/workspaces/`` and ``/mcp_server/api/teams/``.

    Returns the empty set when Neo4j is unreachable (fail-closed).
    """
    if not neo4j_available():
        return set()
    try:
        from neomodel import db

        rows, _ = db.cypher_query(
            "MATCH (l:Library) "
            "WHERE l.owner_username IS NULL OR l.owner_username = $u "
            "RETURN l.uid",
            {"u": username},
        )
        return {r[0] for r in rows if r[0]}
    except Exception as exc:  # pragma: no cover - Neo4j unreachable paths
        logger.warning("Failed to enumerate library UIDs for user %s: %s", username, exc)
        return set()


def all_library_uids() -> list[str]:
    """Return the UIDs of every ``Library`` node in Neo4j.

    Used by trusted in-process callers — the Django admin HTML search
    page, the ``/library/api/search/`` DRF endpoint (gated by Django
    session auth) and the ``search`` management command — as the
    ``resolved_libraries`` argument to :class:`SearchRequest`. These
    callers have already been authenticated/authorized at a coarser
    layer (Django login / DRF session) and the unified auth middleware
    (see ``mcp_server/auth.py``) is the one that resolves narrower
    library sets for MCP bearer tokens.

    Returns ``[]`` when Neo4j is unreachable. Callers that want the
    unrestricted / "admin sees everything" semantics should feed this
    result directly into ``SearchRequest.resolved_libraries``; callers
    that want to distinguish "unrestricted" from "fail-closed empty"
    must pass ``resolved_libraries=None`` for the former instead.
    """
    if not neo4j_available():
        return []
    try:
        from .models import Library

        return [lib.uid for lib in Library.nodes.all() if lib.uid]
    except Exception as exc:  # pragma: no cover - Neo4j unreachable paths
        logger.warning("Failed to enumerate library UIDs for search: %s", exc)
        return []
