"""The importables the vendored conformance pack expects from `tests.conftest`.

The kit's five test files (`tests/kit/test_*.py`, byte-identical to the kit's app template)
import `as_user`, `as_session`, `OWNER` and `HAS_INSTANCES` from here, and under
`pythonpath=['.']` that name resolves only to this root module. Everything else the pack
needs (the `client`, `kit` and `bw_calls` fixtures, the in-memory store reset, the recording
mailer) lives in `tests/kit/conftest.py`, so no pure DFP test acquires an accounts store or a
monkeypatch and the suite keeps its second.

Deselected conformance tests are listed in `DESELECT` by node id with a reason. With the
recorder, the mailer and the seeded principals the set is empty.
"""

from __future__ import annotations

import pytest

OWNER = "rian"
HAS_INSTANCES = False

#: node id -> reason. Empty: every conformance test runs against the local directory.
DESELECT: dict[str, str] = {}


def as_user(client, username: str) -> None:
    """Sign `client` in as `username`: a real session row on the in-memory store, its cookie
    set on the client (the jar is cleared first so one name never carries two cookies)."""
    from tests import _accounts

    _accounts.as_user(client, username)


def as_session(client, **session) -> None:
    """Sign in with an arbitrary session dict: `user`, and optionally the kit's View As keys
    `bw_acting_as` and `bw_acting_mode`, written straight onto the row."""
    from sqlalchemy import update

    from app.models import AuthSession
    from tests import _accounts
    from tests.kit import _env

    token_hash = _accounts.as_user(client, session["user"])
    acting = session.get("bw_acting_as")
    if acting:
        with _env.TestSessionLocal() as db:
            db.execute(update(AuthSession).where(AuthSession.token_hash == token_hash)
                       .values(acting_as=acting, acting_mode=session.get("bw_acting_mode") or "readonly"))
            db.commit()


def pytest_collection_modifyitems(config, items):
    if not DESELECT:
        return
    keep, drop = [], []
    for item in items:
        reason = next((r for node, r in DESELECT.items() if item.nodeid.endswith(node)), None)
        (drop if reason else keep).append(item)
    if drop:
        config.hook.pytest_deselected(items=drop)
        items[:] = keep
