"""Diagnostic: per-partition bridge-orbit size distribution for a dual,
logging EVERY partition. Separates BFS time from witness-check time, and
records whether each orbit exhausted below the cap. Also reports if any
witness is found (early YES)."""
import sys
import os
import time
sys.path.insert(0, '/Users/didericis/Code/math-research/papers/'
                'level_resolutions_of_maximal_planar_graphs/experiments')
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from load_holton_mckay import parse_planar_code
from tutte_dual_treecolor import dual_triangulation
from exhaustive_bridge import valid_parity_partitions
from fast_bridge import EdgeCode
from fast_decide import expand_and_check


def run(i, cap, time_cap):
    graphs = parse_planar_code('experiments/nonham38m4.pc')
    G, _ = dual_triangulation(graphs[i][0])
    n = G.number_of_nodes()
    code = EdgeCode(G.nodes())
    code.state0 = code.state_of(G)
    parts = list(valid_parity_partitions(G))
    print(f'dual {i}: {len(parts)} partitions, cap={cap}, time_cap={time_cap}s',
          flush=True)
    sizes = []
    for j, labels in enumerate(parts):
        t0 = time.time()
        seen = {code.state0}
        frontier = [code.state0]
        wit = False
        capped = False
        while frontier and len(seen) < cap:
            if time.time() - t0 > time_cap:
                capped = True
                break
            new = []
            for st in frontier:
                w, neigh = expand_and_check(st, code, labels, n)
                if w:
                    wit = True
                    break
                for ns in neigh:
                    if ns not in seen:
                        seen.add(ns)
                        new.append(ns)
            if wit:
                break
            frontier = new
        if len(seen) >= cap:
            capped = True
        st_tag = 'WITNESS' if wit else ('cap' if capped else 'exhausted')
        sizes.append((len(seen), st_tag))
        print(f'  [{j}] {st_tag} orbit={len(seen)} {time.time()-t0:.1f}s',
              flush=True)
        if wit:
            print(f'dual {i}: BRIDGE-DERIVED (witness at partition {j})',
                  flush=True)
            return
    exh = [s for s, t in sizes if t == 'exhausted']
    capped_ct = sum(1 for s, t in sizes if t == 'cap')
    print(f'\ndual {i}: no witness. exhausted={len(exh)}/{len(parts)}, '
          f'capped={capped_ct}, largest_exhausted={max(exh) if exh else 0}',
          flush=True)


if __name__ == '__main__':
    i = int(sys.argv[1]) if len(sys.argv) > 1 else 0
    cap = int(sys.argv[2]) if len(sys.argv) > 2 else 500000
    tcap = int(sys.argv[3]) if len(sys.argv) > 3 else 60
    run(i, cap, tcap)
