#!/usr/bin/env python3
"""Read selected Python distribution metadata. No installs, network, or target imports.

Run with the interpreter that actually runs ComfyUI. This is not a sandbox:
Python's normal startup hooks still apply. Output is an environment inventory,
not a compatibility assessment. Review it before sharing.
"""
from __future__ import annotations
import argparse
import importlib.metadata as metadata
import json
import platform
import re
import sys
from typing import Any

NAME = re.compile(r"[A-Za-z0-9](?:[A-Za-z0-9._-]{0,126}[A-Za-z0-9])?\Z")
DEPENDENCY_NAME = re.compile(r"\s*([A-Za-z0-9][A-Za-z0-9._-]*)")
DEFAULT_DISTRIBUTIONS = ("torch", "numpy", "safetensors", "transformers")

def valid_name(value: str) -> str:
    if not NAME.fullmatch(value):
        raise argparse.ArgumentTypeError("Use a distribution name only, not a URL, path, option or requirement expression.")
    return value

def safe_scalar(value: Any) -> str:
    """Suppress unusual metadata instead of echoing paths, URLs or control text."""
    value = str(value)
    if len(value) > 128 or not re.fullmatch(r"[A-Za-z0-9._+!-]+", value):
        return "[nonstandard metadata omitted]"
    return value

def summarize_distribution(name: str) -> dict[str, Any]:
    result: dict[str, Any] = {"requestedDistribution": name}
    try:
        dist = metadata.distribution(name)
        # Retain dependency names only: Requires-Dist can contain private URLs.
        dependencies = set()
        for requirement in dist.requires or []:
            match = DEPENDENCY_NAME.match(requirement)
            if match:
                dependencies.add(match.group(1))
        result.update({
            "status": "metadata-found",
            "recordedName": safe_scalar(dist.metadata.get("Name", name)),
            "version": safe_scalar(dist.version),
            "declaredDependencyNames": sorted(dependencies, key=str.casefold),
            "constraintsAndOriginsOmitted": True,
        })
    except metadata.PackageNotFoundError:
        result["status"] = "metadata-not-found"
    except Exception as exc:
        # Do not echo raw exception messages: they may contain local paths.
        result.update(status="metadata-error", errorType=type(exc).__name__)
    return result

def build_report(names: list[str], *, include_paths: bool = False) -> dict[str, Any]:
    if len(names) > 64:
        raise ValueError("At most 64 distributions may be inspected in one run.")
    unique: dict[str, str] = {}
    for name in names:
        valid_name(name)
        unique.setdefault(re.sub(r"[-_.]+", "-", name).lower(), name)
    report: dict[str, Any] = {
        "schemaVersion": 1,
        "tool": "comfyui-world-environment-metadata",
        "pythonVersion": platform.python_version(),
        "implementation": platform.python_implementation(),
        "operatingSystem": platform.system(),
        "machine": platform.machine(),
        "virtualEnvironment": sys.prefix != sys.base_prefix,
        "pathsIncludedByRequest": include_paths,
        "distributions": [summarize_distribution(name) for name in unique.values()],
        "checksNotPerformed": ["GPU availability", "binary ABI", "package import", "node registration", "workflow execution", "network access"],
        "notice": "Distribution metadata is not proof of importability or compatibility; some editable installs may not be discovered. Review output locally before sharing.",
    }
    if include_paths:
        report["privatePaths"] = {"executable": sys.executable, "prefix": sys.prefix, "basePrefix": sys.base_prefix}
    return report

def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--distribution", action="append", type=valid_name,
                        help="Installed distribution to inspect; repeat for multiple packages.")
    parser.add_argument("--include-paths", action="store_true",
                        help="Explicitly include private interpreter paths; review before sharing.")
    args = parser.parse_args(argv)
    try:
        report = build_report(args.distribution or list(DEFAULT_DISTRIBUTIONS), include_paths=args.include_paths)
        print(json.dumps(report, ensure_ascii=False, indent=2))
    except (ValueError, argparse.ArgumentTypeError) as exc:
        parser.error(str(exc))
    return 0

if __name__ == "__main__":
    raise SystemExit(main())
