<?php
declare(strict_types=1);
final class ConfigWriteAudit
{
    private $runtime;private $tenant;
    public function __construct(string $runtime,int $tenant){if($tenant!==2147001321)throw new RuntimeException('Audit tenant');$this->runtime=$runtime;$this->tenant=$tenant;}
    private static function parts(string $s):array{$out=[];$buf='';$quote='';$n=strlen($s);for($i=0;$i<$n;$i++){$c=$s[$i];if($quote!==''){$buf.=$c;if($c==='\\'&&$i+1<$n){$buf.=$s[++$i];continue;}if($c===$quote){if($i+1<$n&&$s[$i+1]===$quote){$buf.=$s[++$i];continue;}$quote='';}continue;}if($c==="'"||$c==='"'||$c==='`'){$quote=$c;$buf.=$c;continue;}if($c===','){$out[]=trim($buf);$buf='';continue;}$buf.=$c;}if($quote!=='')throw new RuntimeException('Unclosed audit literal');$out[]=trim($buf);return $out;}
    private static function id(string $s):int{$s=trim($s);if(strlen($s)>1&&$s[0]==="'"&&substr($s,-1)==="'")$s=substr($s,1,-1);if(!preg_match('/^[0-9]+$/D',$s)||(int)$s<=0)throw new RuntimeException('Invalid positive audit integer');return (int)$s;}
    public function observe($sql):void{$sql=(string)$sql;if(!preg_match('/^\s*(INSERT|UPDATE|DELETE|REPLACE|MERGE|TRUNCATE|ALTER|DROP|CREATE)\b/i',$sql,$m))return;$op=strtoupper($m[1]);$table='unknown';$pass=false;$reason='Unsupported frozen DML';$map=json_decode((string)file_get_contents($this->runtime.'/private-owned-map.json'),true);
        try{$data=[];
            if($op==='INSERT'&&preg_match('/^\s*INSERT\s+INTO\s+([^\s(]+)\s*\((.*?)\)\s*VALUES\s*\((.*)\)\s*;?\s*$/is',$sql,$p)){$table=strtolower(str_replace(['`','"'],'',$p[1]));$cols=self::parts($p[2]);$vals=self::parts($p[3]);if(count($cols)!==count($vals))throw new RuntimeException('Insert arity');foreach($cols as $i=>$col){$k=strtolower(trim($col,' `"'));if(isset($data[$k]))throw new RuntimeException('Duplicate inserted field');$data[$k]=$vals[$i];}}
            elseif($op==='INSERT'&&preg_match('/^\s*INSERT\s+INTO\s+([^\s]+)\s+SET\s+(.*?)\s*;?\s*$/is',$sql,$p)){$table=strtolower(str_replace(['`','"'],'',$p[1]));foreach(self::parts($p[2]) as $part){if(!preg_match('/^\s*[`"]?([a-z0-9_]+)[`"]?\s*=\s*(.*)$/iD',$part,$a))throw new RuntimeException('Unsupported inserted assignment');$k=strtolower($a[1]);if(isset($data[$k]))throw new RuntimeException('Duplicate inserted field');$data[$k]=$a[2];}}
            elseif($op==='DELETE'&&preg_match('/^\s*DELETE\s+FROM\s+([^\s]+)\s+WHERE\s+(.*?)\s*;?\s*$/is',$sql,$p)){$table=strtolower(str_replace(['`','"'],'',$p[1]));if($table!=='yoshop_health')throw new RuntimeException('Only owned health difference DELETE');$where=trim(str_replace(['(',')','`','"'],'',$p[2]));$atoms=preg_split('/\s+AND\s+/i',$where);$fields=[];if(count($atoms)!==3)throw new RuntimeException('Health requires exact store/staff/health scope');foreach($atoms as $atom){$atom=trim($atom);if(preg_match('/^(?:yoshop_health\.)?(store_id|staff_id)\s*=\s*(\x27?[0-9]+\x27?)\s*$/iD',$atom,$a)){$k=strtolower($a[1]);if(isset($fields[$k]))throw new RuntimeException('Duplicate scope');$fields[$k]=self::id($a[2]);}elseif(preg_match('/^(?:yoshop_health\.)?health\s+IN\s+([0-9,\x27\s]+)$/iD',$atom,$a)){if(isset($fields['health']))throw new RuntimeException('Duplicate health scope');$fields['health']=[];foreach(self::parts($a[1]) as $v){$n=self::id($v);if($n>5)throw new RuntimeException('Invalid health enum');$fields['health'][]=$n;}}else throw new RuntimeException('Unsupported health scope');}$pass=isset($fields['store_id'],$fields['staff_id'],$fields['health'])&&$fields['store_id']===$this->tenant&&$fields['staff_id']===($map['staff_id']??0)&&count($fields['health'])>0;$reason='Exact independent owned staff/store and explicit valid health set';}
            if($op==='INSERT'){$pass=in_array($table,['yoshop_athlete_master','yoshop_athlete_pal','yoshop_health'],true)&&isset($data['store_id'],$data['staff_id'])&&self::id($data['store_id'])===$this->tenant&&self::id($data['staff_id'])===($map['staff_id']??0);if($table==='yoshop_athlete_pal')$pass=$pass&&isset($data['master_id'])&&self::id($data['master_id'])>0;if($table==='yoshop_health')$pass=$pass&&isset($data['health'])&&self::id($data['health'])<=5;$reason=$table==='yoshop_athlete_pal'?'Own staff/store; positive master FK independently verified AFTER commit':'Explicit own staff/store insert';}
        }catch(Throwable $e){$pass=false;$reason=$e->getMessage();}
        file_put_contents($this->runtime.'/private-write-sql.jsonl',json_encode(['sql'=>$sql,'pass'=>$pass])."\n",FILE_APPEND|LOCK_EX);file_put_contents($this->runtime.'/write-audit.jsonl',json_encode(['operation'=>$op,'table'=>$table,'owned_scope_verified'=>$pass,'reason'=>$reason])."\n",FILE_APPEND|LOCK_EX);if(!$pass)throw new RuntimeException('Frozen write audit rejected '.$op.' '.$table.' '.$reason);
    }
}
