"""conftest.py for callback_authority_gate regression tests.

Ensures worktree root is on sys.path so that task-2646 utils modules
are loaded from the worktree, not from live workspace.

This conftest is loaded before test modules are collected, ensuring
that worktree-local dispatch and utils packages take priority over
live workspace versions.

Path layout (relative to this file):
  conftest.py  ←→  parents[0] = callback_authority_gate/
                    parents[1] = regression/
                    parents[2] = tests/
                    parents[3] = worktree root (task-2646-dev3/)
"""
from __future__ import annotations

import sys
from pathlib import Path

# 3 levels up from this file: callback_authority_gate/ → regression/ → tests/ → worktree root
_WORKTREE_ROOT = Path(__file__).resolve().parents[3]

# Guarantee worktree root is first on sys.path (must precede live workspace)
if str(_WORKTREE_ROOT) not in sys.path:
    sys.path.insert(0, str(_WORKTREE_ROOT))
elif sys.path[0] != str(_WORKTREE_ROOT):
    try:
        sys.path.remove(str(_WORKTREE_ROOT))
    except ValueError:
        pass
    sys.path.insert(0, str(_WORKTREE_ROOT))

# Ensure that the task-2646 utils modules (new files only in the worktree)
# can be found. The live workspace's utils/ does not contain these modules,
# so we must ensure the worktree's utils is used.
#
# Strategy: clear 'utils' from sys.modules if it was loaded from live workspace,
# so that the next import resolves from worktree root (now first in sys.path).

_live_workspace = "/home/jay/workspace"

_utils_mod = sys.modules.get("utils")
_utils_file = getattr(_utils_mod, "__file__", None) or ""
_utils_path = getattr(_utils_mod, "__path__", [])
_utils_from_live = (
    _utils_mod is not None
    and (
        _live_workspace + "/utils" in _utils_file
        or any(_live_workspace + "/utils" in str(p) for p in _utils_path)
    )
)

_to_clear = set()
if _utils_from_live:
    # Clear all utils.* from live workspace so worktree utils takes over
    for k in list(sys.modules.keys()):
        if k == "utils" or k.startswith("utils."):
            _to_clear.add(k)

# Also clear any dispatch.* that may conflict
_dispatch_mod = sys.modules.get("dispatch")
_dispatch_file = getattr(_dispatch_mod, "__file__", None) or ""
_dispatch_from_live = (
    _dispatch_mod is not None
    and _live_workspace + "/dispatch" in _dispatch_file
)
if _dispatch_from_live:
    for k in list(sys.modules.keys()):
        if k == "dispatch" or k.startswith("dispatch."):
            _to_clear.add(k)

# Also clear the specific new task-2646 modules regardless
_task_2646_modules = {
    "utils.callback_registration",
    "utils.callback_authority_validator",
    "utils.callback_source_cross_checker",
}
_to_clear.update(_task_2646_modules)

for k in _to_clear:
    sys.modules.pop(k, None)


# ── task-2646: pre-pin worktree dispatch package into sys.modules ─────────────
# The worktree contains BOTH `dispatch/` (real package) AND `tests/dispatch/`
# (an unrelated, empty package used as a test-id namespace). pytest's import
# mode places `tests/` on sys.path during collection, so a bare ``import
# dispatch`` triggered later by register_callback() can resolve to the empty
# `tests/dispatch/__init__.py` and fail to find `normal_fallback_callback_helper`.
#
# To prevent that, we explicitly load the WORKTREE dispatch package via
# spec_from_file_location and pin it in sys.modules under both "dispatch" and
# "dispatch.normal_fallback_callback_helper" so register_callback's lazy import
# always resolves to the real worktree package — regardless of what pytest
# subsequently does to sys.path.
import importlib.util as _ilu

_worktree_dispatch_init = _WORKTREE_ROOT / "dispatch" / "__init__.py"
_worktree_helper_mod = _WORKTREE_ROOT / "dispatch" / "normal_fallback_callback_helper.py"

if _worktree_dispatch_init.exists() and _worktree_helper_mod.exists():
    # Step 1: pin worktree dispatch package
    if "dispatch" not in sys.modules or _WORKTREE_ROOT.as_posix() not in (
        getattr(sys.modules.get("dispatch"), "__file__", "") or ""
    ):
        _spec_pkg = _ilu.spec_from_file_location(
            "dispatch",
            str(_worktree_dispatch_init),
            submodule_search_locations=[str(_WORKTREE_ROOT / "dispatch")],
        )
        if _spec_pkg is not None and _spec_pkg.loader is not None:
            _pkg = _ilu.module_from_spec(_spec_pkg)
            sys.modules["dispatch"] = _pkg
            try:
                _spec_pkg.loader.exec_module(_pkg)
            except Exception:
                # If full __init__ load fails (heavy deps), keep the partial
                # package — submodule import below will still succeed.
                pass
    # Step 2: pin worktree dispatch.normal_fallback_callback_helper
    if "dispatch.normal_fallback_callback_helper" not in sys.modules:
        _spec_helper = _ilu.spec_from_file_location(
            "dispatch.normal_fallback_callback_helper",
            str(_worktree_helper_mod),
        )
        if _spec_helper is not None and _spec_helper.loader is not None:
            _helper = _ilu.module_from_spec(_spec_helper)
            sys.modules["dispatch.normal_fallback_callback_helper"] = _helper
            try:
                _spec_helper.loader.exec_module(_helper)
            except Exception:
                # On exec failure, drop the half-loaded module so a later
                # natural import can retry from sys.path.
                sys.modules.pop("dispatch.normal_fallback_callback_helper", None)
