"""Scan a workspace directory for git repos and classify their forge remotes."""

from __future__ import annotations

import fnmatch
import re
import subprocess
from pathlib import Path

from project_hub.core.config import Config
from project_hub.core.models import Repo

# SSH:   git@HOST:PATH.git
# HTTPS: https://HOST/PATH.git  (trailing .git is optional)
_SSH_RE = re.compile(r"^git@([^:]+):(.+?)(?:\.git)?$")
_HTTPS_RE = re.compile(r"^https?://([^/]+)/(.+?)(?:\.git)?$")


def _parse_remote(url: str) -> tuple[str | None, str | None]:
    m = _SSH_RE.match(url)
    if m:
        return m.group(1), m.group(2)
    m = _HTTPS_RE.match(url)
    if m:
        return m.group(1), m.group(2)
    return None, None


def _get_remote_url(repo_path: Path) -> str | None:
    result = subprocess.run(
        ["git", "remote", "get-url", "origin"],
        cwd=repo_path,
        capture_output=True,
        text=True,
        check=False,
    )
    if result.returncode != 0:
        return None
    return result.stdout.strip() or None


def discover_repos(workspace_root: Path, config: Config) -> list[Repo]:
    """Discover git repos under workspace_root, applying include/exclude filters."""
    repos: list[Repo] = []

    for child in sorted(workspace_root.iterdir()):
        if not child.is_dir():
            continue
        if child.name.startswith("."):
            continue
        if not (child / ".git").exists():
            continue
        if config.include and not fnmatch.fnmatch(child.name, config.include):
            continue
        if child.name in config.exclude:
            continue

        remote_url = _get_remote_url(child) or ""
        forge_host, project_path = _parse_remote(remote_url)
        forge_cfg = config.forges.get(forge_host) if forge_host else None
        forge_type = forge_cfg.get("type") if forge_cfg else None
        has_forge = forge_type is not None

        repos.append(
            Repo(
                name=child.name,
                path=str(child),
                remote_url=remote_url,
                forge_host=forge_host,
                forge_type=forge_type,
                has_forge=has_forge,
                project_path=project_path,
            )
        )

    return repos
