"""Socket path resolution for engram daemon.

Centralizes the logic for determining the Unix socket path, used by:
- daemon.py (server)
- cli.py (client)
- mcp_server.py (client)

Priority order:
1. CLAUDE_ENGRAM_SOCKET env var (explicit override)
2. CLAUDE_MEMORY_SOCKET env var (legacy, backward compat)
3. XDG_RUNTIME_DIR/claude-engram.sock (if set)
4. /run/user/$UID/claude-engram.sock (if exists)
5. /tmp/claude-engram.sock (fallback)

The XDG_RUNTIME_DIR and /run/user paths are preferred because:
- They're per-user tmpfs, not subject to tmpwatch/tmpreaper cleanup
- Standard location for user daemons (dbus, systemd use them)
- Automatically cleaned on logout (correct lifecycle)
"""

from __future__ import annotations

import os
from pathlib import Path

SOCKET_FILENAME = "claude-engram.sock"


def _get_run_user_dir() -> Path | None:
    """Get /run/user/$UID directory if it exists and is accessible.

    Returns None if the directory doesn't exist or isn't accessible.
    """
    try:
        uid = os.getuid()
        run_user_path = Path(f"/run/user/{uid}")
        if run_user_path.exists() and run_user_path.is_dir() and os.access(run_user_path, os.W_OK):
            return run_user_path
    except (OSError, AttributeError):
        # os.getuid() not available on Windows, or permission error
        pass
    return None


def resolve_socket_path() -> Path:
    """Resolve the socket path based on environment and system availability.

    Priority:
    1. CLAUDE_ENGRAM_SOCKET env var
    2. CLAUDE_MEMORY_SOCKET env var (legacy)
    3. XDG_RUNTIME_DIR (if set)
    4. /run/user/$UID (if exists)
    5. /tmp (fallback)
    """
    # 1. Explicit env override (new name)
    if "CLAUDE_ENGRAM_SOCKET" in os.environ:
        return Path(os.environ["CLAUDE_ENGRAM_SOCKET"])

    # 2. Legacy env var (backward compat)
    if "CLAUDE_MEMORY_SOCKET" in os.environ:
        return Path(os.environ["CLAUDE_MEMORY_SOCKET"])

    # 3. XDG_RUNTIME_DIR (standard for user daemons)
    xdg_runtime = os.environ.get("XDG_RUNTIME_DIR")
    if xdg_runtime:
        xdg_path = Path(xdg_runtime)
        if xdg_path.exists() and xdg_path.is_dir():
            return xdg_path / SOCKET_FILENAME

    # 4. /run/user/$UID (common on Linux)
    run_user = _get_run_user_dir()
    if run_user:
        return run_user / SOCKET_FILENAME

    # 5. Fallback to /tmp
    return Path("/tmp") / SOCKET_FILENAME  # noqa: S108


# Module-level constant for backward compatibility with existing imports
SOCKET_PATH = resolve_socket_path()
