<?php
declare(strict_types=1);date_default_timezone_set('Asia/Shanghai');define('CDX_SPORT_CONTEXT',true);require __DIR__.'/preflight.php';$lease=json_decode(file_get_contents(__DIR__.'/private-lease.json'),true);$marker='CDXSP10'.$lane.strtoupper(bin2hex(random_bytes(3)));$out=['lane'=>$lane,'marker'=>$marker,'failure'=>null,'cases'=>[],'source_checks'=>[]];$own=[];$bodies=[];
$admin=$q('SELECT ID,UUID FROM '.$p.'user WHERE ID=(SELECT MIN(ID) FROM '.$p.'user WHERE TYPE=0 AND IS_DELETE=0)')[0];require_once $root.'/application/base/Security.php';$token=\app\base\Security::encrypt(implode("\t",[(string)$admin['id'],(string)$admin['uuid'],'CDXSP10ADMIN','0','','','CDXSP10ADMIN']));
$shape=static function($v)use(&$shape){if(is_object($v)){$r=[];foreach(get_object_vars($v)as $k=>$x)$r[$k]=$shape($x);ksort($r);return ['object'=>$r];}return is_array($v)?['array'=>array_map($shape,$v)]:(is_int($v)||is_float($v)?'number':gettype($v));};
$rq=static function(string $label,string $module,string $action,array $params,int $expected)use($lane,$token,&$out,&$bodies,$shape,$check):array{$path='/p/'.$module.'/'.$action;$raw=(string)file_get_contents('http://127.0.0.1:'.($lane==='B'?18301:18302).$path,false,stream_context_create(['http'=>['method'=>'POST','header'=>'token: '.$token."\r\nContent-Type: application/x-www-form-urlencoded\r\n",'content'=>http_build_query($params),'ignore_errors'=>true,'timeout'=>30]]));$body=json_decode($raw,true);$bodies[$module.'.'.$label]=json_decode($raw);$out['cases'][]=['scenario'=>$module.'.'.$label,'method'=>'POST','path'=>$path,'code'=>$body['code']??null,'wire_shape'=>$shape(json_decode($raw)),'raw_wire_sha256'=>hash('sha256',$raw)];$check(($body['code']??null)===$expected,'Unexpected result '.$module.'.'.$label);return $body;};
$verify=static function(string $module,string $table,string $label)use($rq,&$own,$q,$p,$check,&$out):void{$r=$q('SELECT * FROM '.$p.$table.' WHERE UUID=?',[$own[$module]['uuid']])[0];$body=$rq($label,$module,'info',['uuid'=>$r['uuid']],0);$check(is_array($body['data'])&&count($body['data'])===count($r),'All original fields present');$diff=[];foreach($r as $k=>$v){$a=$body['data'][$k]??null;$same=$a===$v;if(!$same&&is_numeric($a)&&is_numeric($v))$same=(string)$a===(string)$v;if(!$same)$diff[]=$k;}$check($diff===[],'All original field source values');$out['cases'][count($out['cases'])-1]['all_source_fields_equal']=true;$out['cases'][count($out['cases'])-1]['source_column_count']=count($r);$out['cases'][count($out['cases'])-1]['create_time_length']=strlen($body['data']['create_time']);};
try{
 $boundary=json_decode((string)file_get_contents('http://127.0.0.1:'.($lane==='B'?18301:18302).'/__poc_boundary'),true);$check($boundary['allowlist']==='owned-sport-archives-only'&&$boundary['external_stubs']&&$boundary['original_debug']===$report['original_debug'],'Boundary');
 foreach(['sportEducation'=>'sport_education','sportExperience'=>'sport_experience']as $module=>$table){if((($argv[1]??'')!==''&&$module!==$argv[1])||!$report['tables'][$table]['safe'])continue;$params=$module==='sportEducation'?['staff_uuid'=>$lease['staff']['uuid'],'start_date'=>'2010-01-01','end_date'=>'2010-01-02','head_coach'=>'CDX主教练','assistant_coach1'=>'CDX助教一','assistant_coach2'=>'CDX助教二','scientific_staff'=>'CDX科研','medical_staff'=>'CDX医务','demo'=>$marker.'中文\'备注'."\n末行"]:['staff_uuid'=>$lease['staff']['uuid'],'team_name'=>$marker.'测试队','team_coach'=>'CDX教练','in_team_date'=>'2010-01-01','out_team_date'=>'2010-01-02','address'=>'CDX测试地址','demo'=>$marker.'中文\'备注'."\n末行"];
  $rq('initial_list',$module,'lists',['staff_uuid'=>$lease['staff']['uuid']],0);$rq('add',$module,'add',$params,0);$rows=$q('SELECT * FROM '.$p.$table.' WHERE STAFF_UUID=? ORDER BY ID',[$lease['staff']['uuid']]);$rows=array_values(array_filter($rows,static function($r)use($marker){return strpos((string)$r['demo'],$marker)===0;}));$check(count($rows)===1,'Unique created owned marker');$row=$rows[0];$own[$module]=['uuid'=>$row['uuid'],'id'=>(int)$row['id'],'marker'=>$marker,'table'=>$table,'params'=>$params];file_put_contents(__DIR__.'/private-own.json',json_encode($own));chmod(__DIR__.'/private-own.json',0600);foreach($params as $k=>$v)$check($row[$k]===$v,'Request to source '.$k);$verify($module,$table,'info_created');
  $body=$rq('list_created',$module,'lists',['staff_uuid'=>$lease['staff']['uuid'],'page'=>1],0);$matching=array_values(array_filter($body['data']['rows'],static function($r)use($row){return $r['uuid']===$row['uuid'];}));$check(count($matching)===1,'Nonempty owned list');foreach($matching[0]as $k=>$v)$check($v===$row[$k],'Every projected list field source');$out['cases'][count($out['cases'])-1]['projected_source_values_and_types_equal']=true;
  $params['uuid']=$row['uuid'];$params['demo']=$marker.'更新中文\'二';if($module==='sportEducation')$params['head_coach']='CDX新教练';else $params['address']='CDX更新地址';$rq('update',$module,'update',$params,0);$updated=$q('SELECT * FROM '.$p.$table.' WHERE UUID=?',[$row['uuid']])[0];foreach($params as $k=>$v)$check($updated[$k]===$v,'Updated request/source '.$k);$check($updated['create_time']===$row['create_time']&&$updated['create_by']===$row['create_by'],'Immutable create fields');$own[$module]['params']=$params;file_put_contents(__DIR__.'/private-own.json',json_encode($own));$verify($module,$table,'info_updated');$rq('update_repeat',$module,'update',$params,0);
  $before=$q('SELECT * FROM '.$p.$table.' ORDER BY ID');$bad=$params;unset($bad[$module==='sportEducation'?'head_coach':'team_name']);$rq('missing_required',$module,'update',$bad,1);$bad=$params;$bad[$module==='sportEducation'?'start_date':'in_team_date']='not-a-date';$rq('invalid_date',$module,'update',$bad,1);$bad=$params;$bad[$module==='sportEducation'?'head_coach':'team_name']=str_repeat('长',40);$rq('overlong_text',$module,'update',$bad,1);$check($q('SELECT * FROM '.$p.$table.' ORDER BY ID')===$before,'Rejected update source unchanged');$out['source_checks'][$module]=['request_all_fields_read_back'=>true,'rejections_no_mutation'=>true,'create_fields_unchanged'=>true];
 }
}catch(Throwable $e){$out['failure']=['class'=>get_class($e),'reason'=>$e->getMessage()];}
finally{foreach($report['tables']as $table=>$source){if(!$source['safe'])continue;$module=$table==='sport_education'?'sportEducation':'sportExperience';$rows=$q('SELECT * FROM '.$p.$table.(isset($own[$module])?' WHERE ID<>?':'').' ORDER BY ID',isset($own[$module])?[$own[$module]['id']]:[]);$out['natural_tables_unchanged'][$table]=$hash($rows)===$source['sha256'];}$out['retained_owned_rows']=count($own);$out['staff_user_reference_unchanged']=$hash($q('SELECT UUID,NAME,AI_USER_ID,IS_SHOW,JOB_STATUS FROM '.$p.'staff WHERE UUID=?',[$lease['staff']['uuid']])[0])===$report['synthetic_reference']['staff_projection_sha256']&&$hash($q('SELECT ID,UUID,STAFF_UUID,ACCOUNT,TYPE FROM '.$p.'user WHERE ID=?',[(int)$lease['user']['id']])[0])===$report['synthetic_reference']['user_projection_sha256'];foreach(['private-bodies.json'=>$bodies,'private-crud.json'=>$out,'private-baseline.json'=>$report]as $file=>$v){file_put_contents(__DIR__.'/'.$file,json_encode($v,JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));chmod(__DIR__.'/'.$file,0600);}}
echo json_encode($out),"\n";exit($out['failure']?2:0);
