"""All word-boundary occurrences in sanctioned local tree, including slash aliases."""
import json,re,hashlib
from pathlib import Path
p=Path(__file__).parent
tp=p.parents[2]/'adam-y-phylogeny/data/current_tree.json'
old=json.loads((p/'supplement-marker-check.json').read_text())
markers=list(old['marker_matches'])+old['unmatched_markers']
assert len(markers)==len(set(markers))==25
queries=markers+['B877','S8223','Y3088','Z18270']
patterns={m:re.compile(r'\b'+re.escape(m)+r'\b') for m in queries}
res={m:[] for m in queries};nodes={}
def walk(n,path):
 nodes[n['id']]=n
 s=n.get('snps','')
 for m,pat in patterns.items():
  if pat.search(s):res[m].append({'node':n['id'],'path':path,'matching_blocks':[b.strip() for b in s.split(',') if pat.search(b)]})
 for c in n.get('children',[]):walk(c,path+[n['id']])
walk(json.loads(tp.read_text()),[])
tally={'at_J_Y3088':[m for m in markers if any(x['node']=='J-Y3088' for x in res[m])], 'at_immediate_parent':[m for m in markers if any(x['node']=='J-S20075' for x in res[m])], 'not_found':[m for m in markers if not res[m]]}
out={'tree_sha256':hashlib.sha256(tp.read_bytes()).hexdigest(),'method':'All snps fields; case-sensitive regex word boundaries; every matching node and comma-separated alias block retained. Names, not independent mutations.','marker_matches':{m:res[m] for m in markers},'additional_alias_queries':{m:res[m] for m in queries[25:]},'tally':tally,'node_ages':{k:nodes['J-Y3088'][k] for k in ['tmrca','tmrcalowage','tmrcahighage']}}
(p/'supplement-marker-recheck.json').write_text(json.dumps(out,indent=2)+'\n')
print(json.dumps({'counts':{k:len(v) for k,v in tally.items()},'missing':tally['not_found'],'FGC13874':res['FGC13874'],'ages':out['node_ages']},indent=2))
