#!/usr/bin/env python3
# qga-run.py - run a PowerShell snippet inside the win11 VM via qemu-guest-agent.
# Stdin = PS snippet. Stdout = combined stdout, then optional STDERR block,
# then "--- exit N ---". Exit code 0 on PS rc 0, 1 otherwise.
import base64, json, os, subprocess, sys, time

DOMAIN  = os.environ.get('VM_DOMAIN', 'win11')
TIMEOUT = int(os.environ.get('QGA_TIMEOUT', '300'))

def virsh(cmd):
    p = subprocess.run(
        ['virsh', '-c', 'qemu:///system', 'qemu-agent-command', DOMAIN, json.dumps(cmd)],
        capture_output=True, text=True, timeout=120,
    )
    if p.returncode != 0:
        sys.exit(f"virsh err: {p.stderr.strip()}")
    return json.loads(p.stdout)['return']

snippet = sys.stdin.read()
if not snippet.strip():
    sys.exit("qga-run.py: empty PowerShell snippet on stdin")

args = ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', snippet]
pid  = virsh({'execute': 'guest-exec',
              'arguments': {'path': 'powershell.exe', 'arg': args, 'capture-output': True}})['pid']

deadline = time.time() + TIMEOUT
while time.time() < deadline:
    st = virsh({'execute': 'guest-exec-status', 'arguments': {'pid': pid}})
    if st.get('exited'):
        out = base64.b64decode(st.get('out-data', '')).decode('utf-8', 'replace')
        err = base64.b64decode(st.get('err-data', '')).decode('utf-8', 'replace')
        rc  = st.get('exitcode')
        sys.stdout.write(out)
        if err:
            sys.stdout.write('\n--- STDERR ---\n')
            sys.stdout.write(err)
        sys.stdout.write(f'\n--- exit {rc} ---\n')
        sys.exit(0 if rc == 0 else 1)
    time.sleep(0.5)

sys.exit(f"timeout waiting for pid {pid}")
