"""Discrete-time two-worker queue model; no processes, signals or broker involved."""
import json
from pathlib import Path

def run(name,stop_admission,deadline):
    queue=list(zip('ABCDEF',[2,4,7,11,17,23]));active=[];done=[];starts=[]
    for t in range(deadline+1):
        finished=[j for j in active if j['finish']==t]
        done.extend(j['job'] for j in finished)
        active=[j for j in active if j['finish']!=t]
        if t==deadline:break
        if stop_admission and t>=5:continue
        while len(active)<2 and queue:
            job,duration=queue.pop(0)
            active.append(dict(job=job,start=t,finish=t+duration))
            starts.append(dict(job=job,start=t,finish=t+duration))
    return dict(policy=name,deadline=deadline,completed=len(done),interrupted=len(active),
                unclaimed=len(queue),post_signal_starts=sum(x['start']>=5 for x in starts),
                starts=starts,completed_jobs=done)

rows=[run('exit-at-signal',True,5),run('keep-polling-until-16',False,16),
      run('stop-polling-drain-to-16',True,16),run('stop-polling-short-window',True,12)]
assert [(r['completed'],r['interrupted'],r['unclaimed']) for r in rows]==[(2,2,2),(4,2,0),(4,0,2),(3,1,2)]
assert rows[2]['post_signal_starts']==0
assert max(x['finish'] for x in rows[2]['starts'])==15
report=dict(signal_time=5,worker_slots=2,job_durations=[2,4,7,11,17,23],cases=rows,
            assertions='passed',scope='Integer-tick model; acknowledgements and side effects not simulated')
Path(__file__).with_name('results.json').write_text(json.dumps(report,indent=2)+'\n')
print(json.dumps(report,indent=2))
