#!/usr/bin/env python3
"""Grade a solution binary against the Bulgarian test set using the Option-C
groups/weights/dependencies in grade.properties (min-fast per group)."""
import os, subprocess, sys

ROOT="/Users/deyanhadzhi-manich/Desktop/jelly_build"
TESTS=os.path.join(ROOT,"tests")
TASK="jelly"
TL=4.0

def parse_props():
    p={}
    for ln in open(os.path.join(ROOT,"grade.properties")):
        if "=" in ln:
            k,v=ln.strip().split("=",1); p[k]=v
    groups=[]
    for r in p["groups"].split(","):
        a,b=r.split("-"); groups.append((int(a),int(b)))
    weights=[int(x) for x in p["weights"].split(",")]
    deps=[]
    for d in p["dependencies"].split(","):
        s=set()
        d=d.strip()
        if d:
            for part in d.replace(";",",").split(","):
                if "-" in part:
                    a,b=part.split("-"); s|=set(range(int(a),int(b)+1))
                else:
                    s.add(int(part))
        deps.append(s)
    return groups,weights,deps

def run_test(binary, idx):
    inf=os.path.join(TESTS,f"{TASK}.{idx:03d}.in")
    exp=open(os.path.join(TESTS,f"{TASK}.{idx:03d}.sol")).read().strip()
    try:
        r=subprocess.run([binary],stdin=open(inf),capture_output=True,text=True,timeout=TL)
    except subprocess.TimeoutExpired:
        return False,"TLE"
    if r.returncode!=0: return False,"RTE"
    return (r.stdout.strip()==exp), ("OK" if r.stdout.strip()==exp else "WA")

def main():
    binary=sys.argv[1]
    groups,weights,deps=parse_props()
    raw=[True]*len(groups)   # passed all tests in the group (min-fast)
    detail=[]
    for gi,(lo,hi) in enumerate(groups):
        status="pass"
        for idx in range(lo,hi+1):
            ok,why=run_test(binary,idx)
            if not ok:
                status=f"FAIL @ test {idx} ({why})"; raw[gi]=False; break
        detail.append(status)
    # apply dependencies
    final=[False]*len(groups)
    for gi in range(len(groups)):
        final[gi]=raw[gi] and all(final[d] for d in deps[gi]) if all(d<gi for d in deps[gi]) else raw[gi] and all(raw[d] for d in deps[gi])
    # (deps always reference lower-indexed groups here, so the simple form is fine)
    score=sum(weights[gi] for gi in range(len(groups)) if final[gi])
    print(f"=== {os.path.basename(binary)} ===")
    for gi,(lo,hi) in enumerate(groups):
        mark = "✓" if final[gi] else "✗"
        print(f"  group {gi} tests {lo}-{hi} w={weights[gi]:>2} deps={sorted(deps[gi]) or '-'}: {mark} {detail[gi]}")
    print(f"  TOTAL: {score}/100\n")

if __name__=="__main__":
    main()
