"""Parallel-safe path helpers for the federation test supervisor.

Tests running under pytest-xdist need per-worker discriminated
paths for any shared on-disk resource (Unix sockets, lock files,
temp DBs) — otherwise worker N and worker N+1 fight over the same
``/tmp/myapp.sock``. The :func:`default_sock_path` helper reads
the ``PYTEST_XDIST_WORKER`` env var and returns a per-worker path.

Even without pytest-xdist, the helper is the canonical "where do
I put my test daemon's socket?" answer — keeps the answer
consistent across federation projects.
"""

from __future__ import annotations

import os
import tempfile
from pathlib import Path


def default_sock_path(
    prefix: str,
    worker: str | None = None,
    *,
    tmpdir: Path | None = None,
) -> Path:
    """Return a parallel-safe Unix socket path for a test daemon.

    The path shape is ``<tmpdir>/<prefix>-<worker>.sock``. The
    ``<worker>`` segment defaults to the value of the
    ``PYTEST_XDIST_WORKER`` env var (``"gw0"``, ``"gw1"``, etc.
    under pytest-xdist; the literal ``"main"`` outside it).

    Parameters:
      prefix: Project-namespaced label for the socket — typically
        the project's executable name (``"mgf-hrb-server"``,
        ``"vmanager-daemon"``). Used by ``ss``/``lsof`` to
        distinguish federation-test sockets from production ones.
      worker: Explicit worker tag. If ``None``, read from
        ``PYTEST_XDIST_WORKER`` env var; fall back to
        ``"main"``.
      tmpdir: Override the temp-dir root. Defaults to
        :func:`tempfile.gettempdir` (``/tmp`` on Linux). Pass a
        pytest ``tmp_path`` for test isolation.

    Returns:
      :class:`pathlib.Path`. Caller is responsible for unlinking
      the path before binding (sockets don't replace existing
      paths atomically).

    Examples:
      >>> default_sock_path("mgf-hrb-server")  # doctest: +SKIP
      PosixPath('/tmp/mgf-hrb-server-main.sock')
      >>> os.environ["PYTEST_XDIST_WORKER"] = "gw3"  # doctest: +SKIP
      >>> default_sock_path("mgf-hrb-server")  # doctest: +SKIP
      PosixPath('/tmp/mgf-hrb-server-gw3.sock')
    """
    if not prefix or not _is_safe_prefix(prefix):
        msg = (
            f"prefix must be a non-empty filesystem-safe label "
            f"(alphanumerics + - + _), got {prefix!r}"
        )
        raise ValueError(msg)

    if worker is None:
        worker = os.environ.get("PYTEST_XDIST_WORKER", "main")

    if not _is_safe_prefix(worker):
        msg = f"worker tag must be filesystem-safe (alphanumerics + - + _), got {worker!r}"
        raise ValueError(msg)

    root = tmpdir if tmpdir is not None else Path(tempfile.gettempdir())
    return root / f"{prefix}-{worker}.sock"


def _is_safe_prefix(value: str) -> bool:
    """Cheap filesystem-safe check: alphanumerics, dashes,
    underscores only. Rejects path separators + dotfile-leading
    + empty. Keeps the helper from being a path-injection vector."""
    if not value:
        return False
    return all(ch.isalnum() or ch in ("-", "_") for ch in value)


__all__ = ["default_sock_path"]
