import json, re, os
here=os.path.dirname(os.path.abspath(__file__))
tpl=open(os.path.join(here,"template2.html"),encoding="utf-8").read()
data=open(os.path.join(here,"data2.json"),encoding="utf-8").read()
assert "__DATA__" in tpl
out=tpl.replace("__DATA__",data); assert "__DATA__" not in out
p=os.path.join(here,"sf-block-score.html"); open(p,"w",encoding="utf-8").write(out)
print("wrote sf-block-score.html: %d KB"%(len(out)//1024))

errs=[]
# ASCII gate: any raw non-ASCII byte renders as mojibake if the page is decoded
# as Latin-1 (a UTF-8 middle dot showed up as "A·"). Use \uXXXX or &entity;.
nonascii=sorted({c for c in out if ord(c)>127})
if nonascii: errs.append("non-ASCII literals present: %s"%[hex(ord(c)) for c in nonascii])
for bad in ("<!doctype","<!DOCTYPE","<html","<head>","<body"):
    if bad in out: errs.append("contains %s"%bad)
if out.count("<title>")!=1: errs.append("title count != 1")
root=re.search(r":root\{(.*?)\}",out,re.S).group(1)
defined=set(re.findall(r"(--[a-z0-9-]+)\s*:",root))
used=set(re.findall(r"var\((--[a-z0-9-]+)",out))
miss=sorted(used-defined-{"--z"})
if miss: errs.append("tokens used but not in bare :root: %s"%miss)
for t in ("div","span","svg","script","style","button","ol","li","p","ul","h1","h2","h3","h4","select","label"):
    o=len(re.findall(r"<%s[\s>]"%t,out)); c=out.count("</%s>"%t)
    if o!=c: errs.append("<%s> %d open vs %d close"%(t,o,c))
d=json.loads(data); n=d["meta"]["n"]
import base64
for k,v in d["scores"].items():
    if len(base64.b64decode(v))!=n: errs.append("scores[%s] len != n"%k)
for k,v in d["raw"].items():
    if len(base64.b64decode(v))!=n: errs.append("raw[%s] len != n"%k)
if len(base64.b64decode(d["cells"]["res"]))!=n: errs.append("res len != n")
if len(base64.b64decode(d["via"]["idx"]))!=n: errs.append("via idx len != n")
for k in d["raw"]:
    if k not in d["rawscale"]: errs.append("raw %s has no rawscale"%k)
keys={f["key"] for f in d["factors"]}
if keys!=set(d["scores"].keys()): errs.append("factor/score key mismatch: %s"%(keys^set(d["scores"].keys())))
for f in d["factors"]:
    for fld in ("key","label","group","prov","w","res","note"):
        if fld not in f: errs.append("factor %s missing %s"%(f.get("key"),fld))
    if f["prov"] not in ("MEASURED","DERIVED","ENCODED"): errs.append("bad prov %s"%f["key"])
if max(d["cells"]["nbi"])>=len(d["nbnames"]): errs.append("nbi out of range")
print("VERIFY:","ALL CHECKS PASSED" if not errs else "FAILED")
for e in errs: print("  !",e)
