#!/usr/bin/env python3
from pathlib import Path
import importlib.util, json, subprocess, tempfile
from html.parser import HTMLParser
ROOT=Path(__file__).resolve().parents[2]; OUT=Path(__file__).resolve().parent
spec=importlib.util.spec_from_file_location('showcase',ROOT/'scripts/build-ai-native-showcase.py');mod=importlib.util.module_from_spec(spec);spec.loader.exec_module(mod)
checks=[]
with tempfile.TemporaryDirectory() as name:
 p=Path(name);subprocess.run(['git','init','-q',str(p)],check=True)
 f=p/'standards-stack/llm-wiki/中文知识.md';f.parent.mkdir(parents=True);f.write_text('知识')
 subprocess.run(['git','-C',str(p),'add','.'],check=True)
 (p/'untracked.md').write_text('untracked')
 original=mod.ROOT;mod.ROOT=p
 assert mod.tracked_files()==['standards-stack/llm-wiki/中文知识.md'];mod.ROOT=original
 checks.append('中文路径保持UTF-8，未跟踪文件不计入资产')
name='AI_AGENT_PROJECT_INTRO_FOR_BEGINNERS.html';text=f'<a href="{mod.PUBLIC_BASE}/{name}#x">x</a><a href="#y">y</a>'
assert mod.normalize_page_anchors(text,Path(name))=='<a href="#x">x</a><a href="#y">y</a>'
checks.append('公开旧版绝对锚点归一到当前文档，已有片段锚点保留')
m=json.loads((OUT/'metrics.json').read_text())
for version,ref in [('baseline',m['baseline_sha']),('current',m['current_sha'])]:
 paths=subprocess.check_output(['git','ls-tree','-r','--name-only','-z',ref],cwd=ROOT).decode().split('\0')
 assert sum(x.startswith('standards-stack/agent-skills/skills/') and x.endswith('/SKILL.md') for x in paths)==m[version]['skills']
 assert sum(x.startswith('standards-stack/llm-wiki/') and x.endswith('.md') for x in paths)==m[version]['wiki']
checks.append('两个Git版本Skill及Wiki按UTF-8树路径复算一致')
import csv
for version,ref in [('baseline',m['baseline_sha']),('current',m['current_sha'])]:
 raw=subprocess.check_output(['git','show',ref+':control/task-index/tasks.tsv'],cwd=ROOT).decode()
 assert len(list(csv.DictReader(raw.splitlines(),delimiter='\t')))==m[version]['tasks']
checks.append('任务索引两个版本行数复算一致；不按完成状态推断')
for row in csv.DictReader((OUT/'evidence-ledger.csv').open()):assert (ROOT/row['source_path']).is_file()
checks.append('5项证据路径可解析')
class HTML(HTMLParser):
 def __init__(self):super().__init__();self.ids=[];self.hrefs=[];self.resources=[]
 def handle_starttag(self,tag,attrs):
  d=dict(attrs)
  if 'id' in d:self.ids.append(d['id'])
  if tag=='a':self.hrefs.append(d.get('href',''))
  if tag in ['script','img','link']:self.resources.append(d.get('src',d.get('href','')))
for name in ['CPT_AI_ENABLEMENT_BRIEF.html',*mod.PAGES]:
 p=HTML();s=(ROOT/name).read_text();p.feed(s)
 assert len(p.ids)==len(set(p.ids)),name+' duplicate IDs'
 assert all(x[1:] in p.ids for x in p.hrefs if x.startswith('#')),name+' bad fragment'
 assert '2026-09-26' in s
 if name!='CPT_AI_ENABLEMENT_BRIEF.html':assert 'CPT_AI_ENABLEMENT_BRIEF.html' in p.hrefs
 if name=='CPT_AI_ENABLEMENT_BRIEF.html':assert all(not r or r.startswith('data:') for r in p.resources)
checks.append('4页ID唯一、片段完整、三页连通公司页；公司页不依赖外部资源')
browser_file=OUT/'gallery-browser-validation.json'
if not browser_file.exists(): browser_file=OUT/'differentiated-browser-validation.json'
if not browser_file.exists(): browser_file=OUT/'plain-browser-validation.json'
if not browser_file.exists(): browser_file=OUT/'browser-validation.json'
browser=json.loads(browser_file.read_text())
assert len(browser)==8
assert all(x['width']==x['scrollWidth'] and not x['brokenImages'] and not x['brokenAnchors'] and not x['overflow'] and not x['errors'] for x in browser)
checks.append('4页×2视口，零横向溢出/破图/坏锚点/运行错误')
(OUT/'validation.json').write_text(json.dumps({'status':'pass','checks':checks},ensure_ascii=False,indent=2)+'\n')
print('\n'.join(checks))
