"""Cron (every minute, under flock): take the next queued re-run from the spike API store on prod, run it, publish,
report the state back. One job at a time (the GPU box and Astra budget). Log: jobs/worker.log"""
import json, os, subprocess, sys, time
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
LOG = open(f'{ROOT}/jobs/worker.log', 'a')


def prod(*args):
    out = subprocess.run(['ssh', 'prod', 'cd /home/forge/fal-feedback && python3 cli.py ' + ' '.join(f"'{a}'" for a in args)],
                         capture_output=True, text=True, timeout=60)
    return json.loads(out.stdout or '{}')


def log(t):
    LOG.write(time.strftime('%Y-%m-%dT%H:%M:%SZ ', time.gmtime()) + t + '\n'); LOG.flush()


j = prod('next')
if not j:
    sys.exit(0)
log(f"job {j['id']} {j['asset']}: {j['feedback'][:200]}")
prod('update', j['id'], 'running', 'Astra is rebuilding it in Blender (20 to 40 min)')
r = subprocess.run([sys.executable, f'{ROOT}/tools/rerun.py', j['asset'], j['feedback'].replace("'", ' ')], capture_output=True, text=True)
log(r.stdout[-2000:] + r.stderr[-2000:])
if r.returncode != 0:
    prod('update', j['id'], 'failed', (r.stderr.strip().splitlines() or ['failed'])[-1][:300].replace("'", ' '))
    sys.exit(0)
ver = r.stdout.strip().splitlines()[-1]
prod('update', j['id'], 'running', f'v{ver} built; measuring on the GPU and publishing')
p = subprocess.run([f'{ROOT}/tools/publish_all.sh'], capture_output=True, text=True)
log(p.stdout[-1000:] + p.stderr[-1000:])
if p.returncode != 0:
    prod('update', j['id'], 'failed', f'v{ver} built but publishing failed (worker.log)')
    sys.exit(0)
subprocess.run(['git', '-C', ROOT, 'add', '-A'], capture_output=True)
subprocess.run(['git', '-C', ROOT, 'commit', '-qm', f"re-run {j['asset']} v{ver} (operator feedback)"], capture_output=True)
prod('update', j['id'], 'done', f'v{ver} published', ver)
log(f'job {j["id"]} done v{ver}')
