"""Project tag derivation for multi-project memory isolation.

Derives a project tag using a priority cascade:
1. Explicit config project name
2. Git remote origin URL (org/repo format)
3. Basename of the current working directory
"""

from __future__ import annotations

import re
import subprocess
from pathlib import Path

# Regex to extract org/repo from SSH or HTTPS git URLs
_GIT_REMOTE_RE = re.compile(r"[:/]([^/]+)/([^/]+)$")


def derive_project_tag(
    config_project_name: str | None = None,
    project_dir: Path | None = None,
) -> str | None:
    """Derive a project tag for memory isolation.

    Priority cascade:
        1. ``config_project_name`` -- explicit override from config YAML
        2. Git remote origin URL -- parsed to ``org/repo`` format
        3. ``basename(cwd)`` -- fallback for non-git projects

    Args:
        config_project_name: Explicit project name from user config.
            If provided and non-empty, takes highest priority.
        project_dir: Working directory for git and basename resolution.
            Defaults to ``Path.cwd()`` if not provided.

    Returns:
        A tag string like ``"proj:org/repo"`` or ``"proj:my-project"``,
        or None on unexpected failure.
    """
    try:
        # Priority 1: Explicit config override
        if config_project_name and config_project_name.strip():
            return f"proj:{config_project_name.strip()}"

        cwd = project_dir or Path.cwd()

        # Priority 2: Git remote origin
        tag = _derive_from_git_remote(cwd)
        if tag is not None:
            return tag

        # Priority 3: Directory basename
        return f"proj:{cwd.name}"

    except Exception:  # noqa: BLE001 -- error-safe boundary
        return None


def _derive_from_git_remote(cwd: Path) -> str | None:
    """Extract org/repo from git remote origin URL.

    Handles both SSH (``git@github.com:org/repo.git``) and HTTPS
    (``https://github.com/org/repo.git``) formats.

    Returns:
        ``"proj:org/repo"`` or None if git is unavailable or parsing fails.
    """
    try:
        result = subprocess.run(
            ["git", "remote", "get-url", "origin"],
            capture_output=True,
            text=True,
            timeout=2,
            cwd=str(cwd),
            check=False,
        )
        if result.returncode != 0:
            return None

        url = result.stdout.strip()
        if not url:
            return None

        # Strip trailing .git
        if url.endswith(".git"):
            url = url[:-4]

        match = _GIT_REMOTE_RE.search(url)
        if match:
            org, repo = match.group(1), match.group(2)
            return f"proj:{org}/{repo}"

        return None

    except (subprocess.TimeoutExpired, FileNotFoundError, OSError):
        return None
