"""Core helpers for running pip against curated package mirrors."""

from __future__ import annotations

import os
import shlex
import subprocess
import sys
from typing import Mapping, Optional, Sequence, Tuple

DEFAULT_MIRROR = "ali"
DEFAULT_MIRROR_ENV = "QPIP_DEFAULT_MIRROR"

MIRRORS = {
    "ali": "https://mirrors.aliyun.com/pypi/simple/",
    "tsinghua": "https://pypi.tuna.tsinghua.edu.cn/simple/",
    "douban": "https://pypi.doubanio.com/simple/",
}

MIRROR_ALIASES = {
    "ali": "ali",
    "aliyun": "ali",
    "tsinghua": "tsinghua",
    "tuna": "tsinghua",
    "douban": "douban",
}

NETWORK_SUBCOMMANDS = {"install", "download", "wheel", "index", "search"}
SOURCE_OVERRIDE_FLAGS = {
    "-i",
    "--index-url",
    "--extra-index-url",
    "--find-links",
    "-f",
    "--no-index",
}


def normalize_mirror_name(mirror: str) -> str:
    """Resolve a user-provided mirror name into a canonical key."""
    candidate = mirror.strip().lower()
    try:
        return MIRROR_ALIASES[candidate]
    except KeyError as exc:
        choices = ", ".join(sorted(MIRRORS))
        raise ValueError(f"unsupported mirror '{mirror}', available: {choices}") from exc


def is_mirror_name(value: str) -> bool:
    """Return whether the value maps to a known mirror."""
    try:
        normalize_mirror_name(value)
    except ValueError:
        return False
    return True


def get_default_mirror(
    env: Optional[Mapping[str, str]] = None,
) -> Tuple[str, Optional[str]]:
    """Read the default mirror from the environment with a safe fallback."""
    env_map = os.environ if env is None else env
    configured = env_map.get(DEFAULT_MIRROR_ENV, DEFAULT_MIRROR)
    try:
        return normalize_mirror_name(configured), None
    except ValueError:
        warning = (
            f"{DEFAULT_MIRROR_ENV}={configured!r} is invalid; "
            f"falling back to '{DEFAULT_MIRROR}'."
        )
        return DEFAULT_MIRROR, warning


def detect_subcommand(args: Sequence[str]) -> Optional[str]:
    """Return the first pip subcommand token in the argument list."""
    for arg in args:
        if arg == "--":
            continue
        if not arg.startswith("-"):
            return arg
    return None


def should_inject_mirror(args: Sequence[str]) -> bool:
    """Inject an index URL only for network-facing pip subcommands."""
    if not args:
        return False

    if any(arg in SOURCE_OVERRIDE_FLAGS for arg in args):
        return False

    subcommand = detect_subcommand(args)
    return subcommand in NETWORK_SUBCOMMANDS


def build_pip_command(
    args: Sequence[str],
    mirror: str = DEFAULT_MIRROR,
    python_executable: Optional[str] = None,
) -> list[str]:
    """Build the pip command line for the supplied arguments."""
    if not args:
        raise ValueError("pip arguments cannot be empty")

    resolved_mirror = normalize_mirror_name(mirror)
    command = [python_executable or sys.executable, "-m", "pip", *args]

    if should_inject_mirror(args):
        command.extend(["-i", MIRRORS[resolved_mirror]])

    return command


def format_command(command: Sequence[str]) -> str:
    """Render a subprocess command in a shell-friendly format."""
    if os.name == "nt":
        return subprocess.list2cmdline(list(command))
    return shlex.join(command)


def format_mirrors() -> str:
    """Format the configured mirrors for human-readable CLI output."""
    rows = ["Available mirrors:"]
    for name, url in MIRRORS.items():
        rows.append(f"  {name:<8} {url}")
    return "\n".join(rows)


def run_pip_with_mirror(
    args: Sequence[str],
    mirror: str = DEFAULT_MIRROR,
    dry_run: bool = False,
    python_executable: Optional[str] = None,
) -> int:
    """Execute pip using the current interpreter and an optional mirror."""
    command = build_pip_command(args, mirror=mirror, python_executable=python_executable)
    print(f"[qpip] {format_command(command)}")

    if dry_run:
        return 0

    result = subprocess.run(command, check=False)
    return result.returncode
