from pathlib import Path
import hashlib,json,re,struct,xml.etree.ElementTree as ET
from html.parser import HTMLParser
root=Path(__file__).resolve().parent
artbook=root.parents[1]
checks={}
starting=json.loads((root/'notes/starting-assets-sha256.json').read_text())
changed=[p for p,h in starting.items() if not (artbook/p).is_file() or hashlib.sha256((artbook/p).read_bytes()).hexdigest()!=h]
assert not changed,changed
checks['startingAssets']={'count':len(starting),'changed':changed}
class Links(HTMLParser):
    def __init__(self):super().__init__();self.links=[]
    def handle_starttag(self,tag,attrs):
        self.links.extend(v for k,v in attrs if k in ('href','src'))
parser=Links();parser.feed((root/'index.html').read_text())
missing=[]
for url in parser.links:
    if not url.startswith(('https:','http:','#')) and not (root/url).is_file():missing.append(url)
for md in root.rglob('*.md'):
    for url in re.findall(r'\]\(([^)]+)\)',md.read_text()):
        if not url.startswith(('https:','http:','#')) and not (md.parent/url).is_file():missing.append(str(md)+':'+url)
assert not missing,missing
checks['localLinks']={'checked':len(parser.links),'missing':missing}
svg=list(root.rglob('*.svg'))
for p in svg:
    r=ET.parse(p).getroot();ids={e.get('id') for e in r.iter() if e.get('id')}
    refs=re.findall(r'url\(#([^)]+)\)',p.read_text());assert all(x in ids for x in refs),str(p)
    assert 'http' not in p.read_text().replace('http://www.w3.org/2000/svg',''),str(p)
for p in root.rglob('*.json'):json.loads(p.read_text())
checks['svg']={'count':len(svg),'syntax':'pass','gradientReferences':'pass','externalLinks':'none'}
checks['motion']={'count':len(list((root/'motion').rglob('*.svg'))),'statesPerCharacter':6,'playback':'not-browser-verified','reducedMotionRule':all('prefers-reduced-motion' in p.read_text() for p in (root/'motion').rglob('*.svg'))}
checks['parts']={'separateSVGs':len(list((root/'parts').rglob('*.svg'))),'jointRecords':3,'status':'draft starting-vector shapes'}
checks['images']=[]
for p in root.rglob('*.png'):
    data=p.read_bytes();assert data[:8]==b'\x89PNG\r\n\x1a\n',str(p)
    w,h=struct.unpack('>II',data[16:24]);checks['images'].append({'path':str(p.relative_to(root)),'size':[w,h]})
checks['artworkInspection']='seven final plates and three revisions inspected through view_image'
checks['browserPreview']='blocked: file protocol is not allowed; no workaround used'
checks['source']={'folder':'artbook/editions/first-version','startingExportCommit':'fbdc8415bb9c5cf03ee535a48d754e7748ad054d','date':'2026-10-08'}
(root/'notes/verification.json').write_text(json.dumps(checks,indent=2)+'\n')
manifest={'edition':'first-version','status':'draft-for-review','generator':'built-in imagegen; stdlib draft SVG extraction','files':[]}
for p in sorted(root.rglob('*')):
    if p.is_file() and p.name!='edition-manifest.json':manifest['files'].append({'path':str(p.relative_to(root)),'sha256':hashlib.sha256(p.read_bytes()).hexdigest()})
(root/'edition-manifest.json').write_text(json.dumps(manifest,indent=2)+'\n')
print(json.dumps({'startingAssetsUnchanged':len(starting),'linksChecked':len(parser.links),'SVGs':len(svg),'motionStudies':checks['motion']['count'],'separateParts':checks['parts']['separateSVGs'],'PNGFiles':len(checks['images']),'checks':'pass','browser':'unverified'}))
