#!/usr/bin/env python3
"""测量：不同求解策略产出的输入，实际打到"新边"的比例（乐观求解的落地率）。"""
import os, subprocess, sys, tempfile, collections

AFLBIN, OUTDIR, SEED = sys.argv[1], sys.argv[2], sys.argv[3]

def edges(path: str) -> set:
    with tempfile.NamedTemporaryFile(suffix=".map", delete=False) as t:
        mp = t.name
    try:
        subprocess.run(["afl-showmap", "-t", "5000", "-m", "none", "-q",
                        "-o", mp, "--", AFLBIN, path],
                       stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
                       env={**os.environ, "AFL_MAP_SIZE": "65536"})
        with open(mp) as f:
            return {int(l.split(":")[0]) for l in f if ":" in l}
    finally:
        os.unlink(mp)

base = edges(SEED)
print(f"种子边数: {len(base)}")
stats = collections.defaultdict(lambda: [0, 0, set()])   # [总数, 有新边数, 新边并集]
cum = set(base)
for fn in sorted(os.listdir(OUTDIR)):
    if fn.endswith(".hints"):
        continue
    tag = fn.split("-", 1)[1] if "-" in fn else "nominal(strict)"
    e = edges(os.path.join(OUTDIR, fn))
    new_vs_seed = e - base
    s = stats[tag]
    s[0] += 1
    if new_vs_seed:
        s[1] += 1
    s[2] |= new_vs_seed
print(f"{'策略':<18} {'产出':>5} {'相对种子有新边':>14} {'落地率':>8} {'贡献新边(并集)':>14}")
for tag, (n, hit, ne) in sorted(stats.items()):
    print(f"{tag:<18} {n:>5} {hit:>14} {hit/n*100:>7.1f}% {len(ne):>14}")
