<?php
declare(strict_types=1);
$root=dirname(__DIR__);$cat=json_decode((string)file_get_contents($root.'/content/test_catalog.json'),true);$checks=[];$problems=[];
$books=$cat['books']??[];$loose=$cat['loose_pages']??[];$paths=$cat['paths']??[];
$checks['ten_books']=count($books)===10;$checks['two_loose_pages']=count($loose)===2;$checks['four_paths']=count($paths)===4;
$hashes=[];$totalPages=0;
foreach($books as $b){
 if(count($b['pages']??[])!==8)$problems[]=$b['id'].' does not have 8 pages';
 $totalPages+=count($b['pages']??[]);
 $files=[$b['cover']];foreach($b['pages']??[] as $p)$files[]=$p['art'];
 foreach($files as $f){$p=$root.'/'.$f;if(!is_file($p)){$problems[]='missing art '.$f;continue;}$h=hash_file('sha256',$p);if(isset($hashes[$h]))$problems[]='duplicate art '.$f.' and '.$hashes[$h];else$hashes[$h]=$f;}
 foreach($b['pages']??[] as $p){$txt=implode(' ',$p['paragraphs']??[]);if(strlen(trim($txt))<120)$problems[]=$b['id'].' page '.$p['index'].' is too thin';foreach(['placeholder','lorem ipsum','this is a complete book'] as $bad)if(stripos($txt,$bad)!==false)$problems[]=$b['id'].' contains '.$bad;}
}
$checks['eighty_pages']=$totalPages===80;$checks['ninety_unique_art_assets']=count($hashes)===90;
foreach($paths as $p){foreach($p['steps']??[] as $st){if(($st['kind']??'')==='book'){if((int)$st['end']-(int)$st['start']+1>2)$problems[]=$p['code'].' exceeds two-page excerpt for '.$st['id'];}}}
$checks['excerpt_budget_25_percent']=!array_filter($problems,fn($x)=>str_contains($x,'exceeds two-page'));
$manifest=json_decode((string)file_get_contents($root.'/content/manifestations_test.json'),true);$checks['one_signal_per_book']=count($manifest['items']??[])===10;
$js=file_get_contents($root.'/assets/app.js');
$checks['following_thread_ui']=strpos($js,'FOLLOWING THREAD')!==false;$checks['exploring_book_ui']=strpos($js,'EXPLORING BOOK')!==false;$checks['loose_page_ui']=strpos($js,'LOOSE PAGE')!==false;$checks['future_titles_hidden']=strpos($js,'Unknown')!==false;$checks['book_end_returns_thread']=strpos($js,'Return to Thread →')!==false;$checks['no_public_book_count']=strpos($js,'10 NEW TEST BOOKS')===false;
$pass=!in_array(false,$checks,true)&&count($problems)===0;echo json_encode(['pass'=>$pass,'checks'=>$checks,'problems'=>$problems],JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES),PHP_EOL;exit($pass?0:1);
