#!/usr/bin/env python3
"""Submit Z-Image-Turbo workflow and monitor CPU/threading."""
import paramiko
import json
import time

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('192.168.178.150', username='fabian', key_filename=r'C:\Users\fabia\.ssh\id_ed25519')

def run(cmd, timeout=60, desc=""):
    if desc:
        print(f"\n{'='*60}")
        print(f"  {desc}")
        print(f"{'='*60}")
    _, stdout, stderr = ssh.exec_command(cmd, timeout=timeout)
    out = stdout.read().decode()
    err = stderr.read().decode()
    rc = stdout.channel.recv_exit_status()
    if out.strip():
        lines = out.strip().split('\n')
        if len(lines) > 40:
            print(f"  ... ({len(lines)} lines, showing last 40)")
            print('\n'.join(lines[-40:]))
        else:
            print(out.strip())
    if err.strip():
        lines = err.strip().split('\n')[-10:]
        print(f"STDERR: {chr(10).join(lines)}")
    print(f"  Exit: {rc}")
    return rc, out, err

# Workflow JSON
workflow = {
    "prompt": {
        "1": {
            "class_type": "UnetLoaderGGUF",
            "inputs": {"unet_name": "z_image_turbo-Q5_K_S.gguf"}
        },
        "2": {
            "class_type": "CLIPLoaderGGUF",
            "inputs": {"clip_name": "Qwen3-4B.i1-Q5_K_S.gguf", "type": "qwen_image"}
        },
        "3": {
            "class_type": "VAELoader",
            "inputs": {"vae_name": "ae.safetensors"}
        },
        "4": {
            "class_type": "CLIPTextEncode",
            "inputs": {
                "text": "A majestic mountain landscape at sunset, golden light on snow peaks, crystal lake reflection, photorealistic, 8k",
                "clip": ["2", 0]
            }
        },
        "5": {
            "class_type": "CLIPTextEncode",
            "inputs": {"text": "", "clip": ["2", 0]}
        },
        "6": {
            "class_type": "EmptyLatentImage",
            "inputs": {"width": 1024, "height": 576, "batch_size": 1}
        },
        "7": {
            "class_type": "KSampler",
            "inputs": {
                "model": ["1", 0],
                "seed": 42,
                "steps": 8,
                "cfg": 1.0,
                "sampler_name": "euler",
                "scheduler": "simple",
                "positive": ["4", 0],
                "negative": ["5", 0],
                "latent_image": ["6", 0],
                "denoise": 1.0
            }
        },
        "8": {
            "class_type": "VAEDecode",
            "inputs": {"samples": ["7", 0], "vae": ["3", 0]}
        },
        "9": {
            "class_type": "SaveImage",
            "inputs": {"images": ["8", 0], "filename_prefix": "ZImageTurbo_BC250"}
        }
    }
}

# Upload and submit
sftp = ssh.open_sftp()
with sftp.open('/tmp/zimage_workflow.json', 'w') as f:
    f.write(json.dumps(workflow))
sftp.close()

rc, out, _ = run("bash -c 'curl -s -X POST http://localhost:8188/prompt "
    "-H \"Content-Type: application/json\" "
    "-d @/tmp/zimage_workflow.json'",
    desc="Submit workflow")

try:
    resp = json.loads(out.strip())
    if 'error' in resp:
        print(f"\nERROR: {resp['error']}")
        if 'node_errors' in resp:
            for nid, e in resp['node_errors'].items():
                print(f"  Node {nid}: {e.get('errors', [])}")
        ssh.close()
        exit(1)
    print(f"\nPrompt ID: {resp.get('prompt_id', 'unknown')}")
except:
    print(f"Response: {out.strip()[:500]}")

# Monitor: check CPU usage + log every 15s
print("\n  Monitoring CPU and progress...")
for i in range(80):  # up to 20 minutes
    time.sleep(15)
    
    # Get CPU usage per-thread of ComfyUI process + total system load
    rc, cpu_out, _ = run("bash -c '"
        "PID=$(pgrep -f \"python3 main.py\" | head -1); "
        "if [ -n \"$PID\" ]; then "
        "  echo \"=== Process CPU ===\"; "
        "  ps -p $PID -o pid,%cpu,%mem,nlwp --no-headers; "
        "  echo \"=== System Load ===\"; "
        "  uptime; "
        "  echo \"=== Per-Core ===\"; "
        "  mpstat -P ALL 1 1 2>/dev/null | tail -15 || cat /proc/loadavg; "
        "else echo PROCESS_DEAD; fi'")
    
    rc, log_out, _ = run("bash -c 'tail -5 /home/fabian/comfyui.log 2>/dev/null'")
    
    if 'PROCESS_DEAD' in (cpu_out or ''):
        print("\n  ComfyUI process died!")
        run("bash -c 'tail -50 /home/fabian/comfyui.log'", desc="Death log")
        break
    if 'Prompt executed in' in (log_out or ''):
        print(f"\n  IMAGE GENERATED! (at check {i+1}, ~{(i+1)*15}s)")
        run("bash -c 'tail -30 /home/fabian/comfyui.log'", desc="Completion log")
        break
    if 'Traceback' in (log_out or '') or 'Exception' in (log_out or ''):
        print("\n  ERROR!")
        run("bash -c 'tail -60 /home/fabian/comfyui.log'", desc="Error log")
        break
    
    print(f"  [{i+1}] {(i+1)*15}s elapsed...")

# Check output
run("bash -c 'ls -lah ~/ComfyUI/output/ 2>/dev/null'", desc="Output files")
run("bash -c 'tail -20 /home/fabian/comfyui.log 2>/dev/null'", desc="Final log")

ssh.close()
print("\nDone.")
