"""
CLI entry point: `python -m vram_viz` or `vram-viz` after pip install.

  vram-viz           # launch web dashboard on :5111
  vram-viz --port 80 # custom port
  vram-viz --cli     # one-shot terminal table
  vram-viz --json    # JSON dump
"""

from __future__ import annotations

import argparse
import json
import os
import sys
import time


def _print_table(top: int = 0):
    from .collector import get_gpu_info, get_process_gpu_memory, fmt_bytes, short_name

    gpus = get_gpu_info()
    procs = get_process_gpu_memory()

    print()
    for gpu in gpus:
        frac = gpu.used_mb / gpu.total_mb if gpu.total_mb else 0
        hdr = f"  GPU {gpu.index}: {gpu.name}"
        if gpu.temperature is not None:
            hdr += f"  |  {gpu.temperature}C"
        if gpu.utilization_pct is not None:
            hdr += f"  |  {gpu.utilization_pct}% util"
        print(hdr)
        bar_w = 50
        filled = int(frac * bar_w)
        print(f"  Memory: {gpu.used_mb:.0f} / {gpu.total_mb:.0f} MB  ({frac:.0%})")
        print(f"  {'#' * filled}{'-' * (bar_w - filled)}")
        print()

    if not procs:
        print("  No per-process GPU memory data.")
        return

    total_gpu_bytes = int(gpus[0].total_mb * 1048576) if gpus else 1
    items = procs[:top] if top else procs
    max_n = max((len(short_name(p)) for p in items), default=12)
    max_n = max(max_n, 12)

    print(f"  {'PROCESS':<{max_n}}  {'PID':>7}  {'DEDICATED':>12}  {'SHARED':>10}  {'%GPU':>6}")
    print(f"  {'-' * max_n}  {'-' * 7}  {'-' * 12}  {'-' * 10}  {'-' * 6}")

    for p in items:
        frac = p.dedicated_bytes / total_gpu_bytes
        nm = short_name(p)
        print(f"  {nm:<{max_n}}  {p.pid:>7}  {fmt_bytes(p.dedicated_bytes):>12}  "
              f"{fmt_bytes(p.shared_bytes):>10}  {frac:>5.1%}")

    if top and len(procs) > top:
        rest = sum(p.dedicated_bytes for p in procs[top:])
        print(f"  {'... + ' + str(len(procs) - top) + ' more':<{max_n}}  {'':>7}  {fmt_bytes(rest):>12}")

    print(f"\n  Total tracked: {fmt_bytes(sum(p.dedicated_bytes for p in procs))}\n")


def _print_json():
    from .collector import collect_snapshot
    print(json.dumps(collect_snapshot(), indent=2))


def main():
    parser = argparse.ArgumentParser(
        prog="vram-viz",
        description="Real-time GPU memory analyzer with cyberpunk dashboard",
    )
    parser.add_argument("--port", type=int, default=5111, help="Web UI port (default: 5111)")
    parser.add_argument("--cli", action="store_true", help="Terminal table instead of web UI")
    parser.add_argument("--json", action="store_true", help="JSON output to stdout")
    parser.add_argument("--top", type=int, default=0, help="Show top N processes (CLI mode)")
    parser.add_argument("--watch", type=float, default=0, help="Refresh interval in seconds (CLI mode)")
    args = parser.parse_args()

    if args.json:
        _print_json()
    elif args.cli:
        try:
            while True:
                if args.watch:
                    os.system("cls" if os.name == "nt" else "clear")
                _print_table(args.top)
                if not args.watch:
                    break
                time.sleep(args.watch)
        except KeyboardInterrupt:
            pass
    else:
        from .server import run_server
        run_server(args.port)


if __name__ == "__main__":
    main()
