from pathlib import Path,PurePosixPath
import zipfile,json,hashlib,stat,unicodedata,subprocess,datetime
P=Path('/mnt/data'); W=P/'work4100'; report={'начало_UTC':datetime.datetime.now(datetime.timezone.utc).isoformat(),'архивы':[]}
sets=[('4.9.0',x) for x in ['война','память-уаикс','документы-и-доказательства','набор-владельца']]+[('4.8.0','война')]
for v,k in sets:
 name=f'{k}-{v}-wip.zip'; p=P/name; rec={'имя':name,'существует':p.is_file()};report['архивы'].append(rec)
 if not p.is_file():continue
 expected=next(x for x in json.loads((P/f'война-{v}-wip-проверка-передачи.json').read_text())['архивы'] if x['архив']==name)
 rec['байты']=p.stat().st_size
 with p.open('rb') as f: rec['ша256']=hashlib.file_digest(f,'sha256').hexdigest()
 rec['совпадение_ведомости']=rec['байты']==expected['байты'] and rec['ша256']==expected['ша256']
 assert rec['совпадение_ведомости'],name
 dest=W/'input'/f'{k}-{v}';dest.mkdir(parents=True,exist_ok=True); norm=set(); entries=[]
 with zipfile.ZipFile(p) as z:
  for i in z.infolist():
   n=i.filename; pp=PurePosixPath(n);fold=unicodedata.normalize('NFC',n).casefold()
   assert not (pp.is_absolute() or '..' in pp.parts or '\\' in n or ':' in pp.parts[0] or str(pp)!=n or n!=unicodedata.normalize('NFC',n) or fold in norm or stat.S_ISLNK(i.external_attr>>16)),n
   assert not any(ord(c)<32 or 127<=ord(c)<160 or 0x202a<=ord(c)<=0x202e or 0x2066<=ord(c)<=0x2069 for c in n),n
   norm.add(fold)
   if i.is_dir(): continue
   data=z.read(i);f=dest/n;f.parent.mkdir(parents=True,exist_ok=True);f.write_bytes(data)
   entries.append({'путь':n,'байты':len(data),'ша256':hashlib.sha256(data).hexdigest()})
 rec['CRC_полное_чтение']=True;rec['пути_и_Unicode']=True;rec['файлов']=len(entries)
 proc=subprocess.run(['python',str(dest/'ПРОВЕРИТЬ-ПОДПИСЬ.py')],capture_output=True,text=True,cwd=dest)
 rec['подпись']={'код':proc.returncode,'вывод':proc.stdout,'ошибки':proc.stderr}; assert proc.returncode==0,proc.stdout
 (W/'run'/f'опись-входа-{k}-{v}.json').write_text(json.dumps(entries,ensure_ascii=False,indent=2))
 print(name,rec['файлов'],'OK',flush=True)
 (W/'run'/'проверка-входов.json').write_text(json.dumps(report,ensure_ascii=False,indent=2))
report['окончание_UTC']=datetime.datetime.now(datetime.timezone.utc).isoformat();(W/'run'/'проверка-входов.json').write_text(json.dumps(report,ensure_ascii=False,indent=2))
