"""
The pip wrapper script content.

This script is written into the venv as:
  Scripts/pip.exe  (Windows) — replaces the original pip entry point
  bin/pip          (Unix)

How it works:
  1. User runs `pip install flask` inside the activated venv
  2. This wrapper script runs first
  3. It calls the REAL pip (pip.__main__)
  4. If install/uninstall succeeded, it updates requirements.txt

The wrapper finds the project root by looking for .venvy/config.json
walking up from cwd, exactly like node_modules resolution.
"""

WRAPPER_SCRIPT = '''#!/usr/bin/env python
"""
venvy pip wrapper — auto-tracks installs/uninstalls in requirements.txt
This file was installed by venvy. Do not edit manually.
"""
import sys
import os
import re
import json
import subprocess
from pathlib import Path


def _normalize(name):
    return re.sub(r"[-_.]+", "_", name).lower()


def _find_venvy_root():
    """Walk up from cwd to find .venvy/config.json"""
    cur = Path.cwd().resolve()
    for d in [cur, *cur.parents]:
        cfg = d / ".venvy" / "config.json"
        if cfg.exists():
            return d, cfg
    return None, None


def _get_version(python, pkg):
    r = subprocess.run([python, "-m", "pip", "show", pkg],
                       capture_output=True, text=True)
    for line in r.stdout.splitlines():
        if line.lower().startswith("version:"):
            return line.split(":", 1)[1].strip()
    return None


def _parse_req(req_file):
    if not req_file.exists():
        return {}
    result = {}
    for line in req_file.read_text("utf-8").splitlines():
        s = line.strip()
        if not s or s.startswith("#"):
            continue
        m = re.match(r"^([A-Za-z0-9_\\-\\.]+)", s)
        if m:
            result[_normalize(m.group(1))] = s
    return result


def _write_req(req_file, pkgs):
    req_file.write_text(
        "\\n".join(sorted(pkgs.values(), key=str.lower)) + "\\n",
        "utf-8"
    )


def _clean_pkg_name(pkg):
    return re.sub(r"(\\[.*?\\]|[><=!;].*)", "", pkg).strip()


def _update_requirements(action, packages, python, req_file):
    """Add or remove packages from requirements.txt"""
    # Create file if missing
    if not req_file.exists():
        req_file.touch()

    pkgs = _parse_req(req_file)
    changed = False

    if action == "install":
        for pkg in packages:
            clean = _clean_pkg_name(pkg)
            if not clean:
                continue
            version = _get_version(python, clean)
            if version:
                key = _normalize(clean)
                entry = f"{clean}=={version}"
                if pkgs.get(key) != entry:
                    pkgs[key] = entry
                    changed = True
                    print(f"[venvy] {req_file.name}: added {entry}")
    elif action == "uninstall":
        for pkg in packages:
            clean = _clean_pkg_name(pkg)
            key = _normalize(clean)
            if key in pkgs:
                del pkgs[key]
                changed = True
                print(f"[venvy] {req_file.name}: removed {clean}")

    if changed:
        _write_req(req_file, pkgs)


def main():
    args = sys.argv[1:]

    # Always run the real pip first
    python = sys.executable
    result = subprocess.run([python, "-m", "pip"] + args)
    exit_code = result.returncode

    # Only track on success
    if exit_code != 0 or not args:
        sys.exit(exit_code)

    action = args[0].lower()
    if action not in ("install", "uninstall"):
        sys.exit(exit_code)

    # Find project root
    root, cfg_path = _find_venvy_root()
    if root is None:
        # No venvy project — silently skip tracking
        sys.exit(exit_code)

    # Load config for req file name
    try:
        cfg = json.loads(cfg_path.read_text("utf-8"))
        req_name = cfg.get("req_file", "requirements.txt")
    except Exception:
        req_name = "requirements.txt"

    req_file = root / req_name

    # Collect package names (skip flags like -r, --upgrade, etc.)
    packages = [a for a in args[1:] if not a.startswith("-") and not a.endswith(".txt") and not a.endswith(".cfg")]

    if packages:
        _update_requirements(action, packages, python, req_file)

    sys.exit(exit_code)


if __name__ == "__main__":
    main()
'''
