"""Registry checking utilities."""

import logging
import threading
from typing import Dict
from urllib.parse import quote

import requests

from .config import REGISTRIES

logger = logging.getLogger(__name__)

# Thread-safe cache for registry checks
_registry_cache: Dict[str, bool] = {}
_cache_lock = threading.Lock()

# npm registry requires @ to be unencoded but / to be encoded
# e.g. @grafana/sql -> @grafana%2Fsql  (NOT %40grafana%2Fsql)
def _build_url(registry_url: str, package_name: str, ecosystem: str) -> str:
    if ecosystem == "npm":
        if package_name.startswith("@"):
            # encode only the slash, keep the @
            scope, _, name = package_name[1:].partition("/")
            encoded = f"@{quote(scope)}%2F{quote(name)}"
        else:
            encoded = quote(package_name)
    else:
        encoded = quote(package_name)
    return registry_url.format(package=encoded)


def check_package_exists(package_name: str, ecosystem: str) -> bool:
    """Check if a package exists in public registry."""
    cache_key = f"{ecosystem}:{package_name.lower()}"

    with _cache_lock:
        if cache_key in _registry_cache:
            return _registry_cache[cache_key]

    registry_url = REGISTRIES.get(ecosystem)
    if not registry_url:
        logger.warning(f"Unknown ecosystem: {ecosystem}")
        return False

    url = _build_url(registry_url, package_name, ecosystem)

    try:
        response = requests.get(url, timeout=10)
        exists = response.status_code == 200
        with _cache_lock:
            _registry_cache[cache_key] = exists
        logger.debug(f"Package {package_name} ({ecosystem}): {'exists' if exists else 'NOT FOUND'} [{url}]")
        return exists
    except requests.RequestException as e:
        logger.warning(f"Error checking {package_name} in {ecosystem}: {e}")
        with _cache_lock:
            _registry_cache[cache_key] = True  # assume exists on network error
        return True
