"""Unit-time preemptive model. Priority 0 is most urgent."""
from dataclasses import dataclass


@dataclass
class Job:
    name: str
    arrival: int
    priority: int
    remaining: int
    start: int | None = None
    finish: int | None = None


def run(mask_until=2):
    jobs = [Job("sample", 0, 1, 8), Job("comm", 3, 3, 4),
            Job("urgent", 4, 0, 2)]
    timeline = []
    for now in range(40):
        ready = [j for j in jobs if j.arrival <= now and j.remaining > 0]
        if now < mask_until or not ready:
            timeline.append("idle")
            continue
        current = min(ready, key=lambda j: (j.priority, j.arrival))
        if current.start is None:
            current.start = now
        current.remaining -= 1
        timeline.append(current.name)
        if current.remaining == 0:
            current.finish = now + 1
        if all(j.remaining == 0 for j in jobs):
            break
    return {j.name: j for j in jobs}, timeline


def main():
    jobs, timeline = run()
    assert jobs["sample"].start == 2
    assert jobs["urgent"].start == 4 and jobs["urgent"].finish == 6
    assert jobs["sample"].finish == 12
    assert jobs["comm"].finish == 16
    assert timeline.count("sample") == 8
    masked, _ = run(mask_until=6)
    assert masked["urgent"].start == 6
    print("sample=[2,12), urgent=[4,6), comm=[12,16); sample was preempted")
    print("PASS")


if __name__ == "__main__":
    main()
