"""Expand the distributed LGPL en_GB Hunspell sources into Scroker’s shared, versioned word list."""
import re,json,pathlib
here=pathlib.Path(__file__).resolve().parent
root=here.parent if here.name=='dictionary' else here.parent/'public'
policy=json.loads((root/'dictionary/scroker-additions.json').read_text())
identities=set(policy['identity_roots'].lower().split())
rules={'PFX':{},'SFX':{}}; cross={}
for line in (root/'dictionary/en_GB.aff').read_text(encoding='utf-8-sig').splitlines():
 p=line.split()
 if len(p)==4 and p[0] in rules: cross[p[0],p[1]]=p[2]=='Y'
 if len(p)>=5 and p[0] in rules:
  kind,flag,strip,add,cond=p[:5]
  rules[kind].setdefault(flag,[]).append((strip if strip!='0' else '',add if add!='0' else '',re.compile(('^'+cond) if kind=='PFX' else (cond+'$'))))
def apply(w,kind,flag):
 for strip,add,cond in rules[kind].get(flag,[]):
  if not cond.search(w):continue
  if kind=='PFX':
   if w.startswith(strip):yield add+w[len(strip):]
  elif not strip:yield w+add
  elif w.endswith(strip):yield w[:-len(strip)]+add
words=set()
for line in (root/'dictionary/en_GB.dic').read_text(encoding='utf-8-sig').splitlines()[1:]:
 parts=line.split('/');w=parts[0];flags=parts[1] if len(parts)>1 else ''
 # Capitalised roots require an explicit identity exception.
 if not re.fullmatch('[a-z]{2,10}',w) and w.lower() not in identities:continue
 if '_' in flags:continue
 w=w.lower()
 forms={w}
 for f in flags:
  forms.update(apply(w,'SFX',f));forms.update(apply(w,'PFX',f))
  if cross.get(('PFX',f)):
   for prefixed in apply(w,'PFX',f):
    for s in flags:
     if cross.get(('SFX',s)):forms.update(apply(prefixed,'SFX',s))
 words.update(x.upper() for x in forms if re.fullmatch('[a-z]{2,10}',x))
# A word-game foundation supplies UK/US variants and short-word coverage.
words.update(w.upper() for w in (root/'dictionary/enable1.txt').read_text().splitlines() if re.fullmatch('[a-z]{2,10}',w))
words.update(w.upper() for w in identities if re.fullmatch('[a-z]{2,10}',w))
words.update(w.upper() for w in policy['common_words'].split() if re.fullmatch('[A-Za-z]{2,10}',w))
(root/'dictionary-version.json').write_text(json.dumps({'version':policy['version'],'wordCount':len(words),'minLength':2,'maxLength':10},indent=2)+'\n')
(root/'words.json').write_text(json.dumps(sorted(words),separators=(',',':')))
print(f'{len(words):,} Scroker English words')
