<?php
declare(strict_types=1);
ini_set('display_errors','0');ini_set('log_errors','0');error_reporting(E_ALL);
set_error_handler(function($severity){throw new ErrorException('Sanitized PHP warning',0,$severity);});
$stage='start';$n=0;$sqlLog=[];
function capSame($e,$a): void {global $n;++$n;if($e!==$a){throw new RuntimeException('Capability assertion '.$n);}}
try{
    require __DIR__.'/ProbeRuntime.php';
    $mode=$argv[1]??'';if(!in_array($mode,['native','passthrough'],true)){throw new InvalidArgumentException('Capability mode');}
    $stage='runtime_identity';$identity=runtimeIdentity();$signatures=internalSignatures();
    if($mode==='passthrough'){require __DIR__.'/PassThroughStatement.php';}
    $stage='connect';$pdo=probePdo($mode==='passthrough'?PassThroughStatement::class:null,$mode==='passthrough'?['OLD_ONLY']:[]);
    $stage='mapped_components';$identity['mapped']=mappedComponents($identity);
    $stage='effective_attributes';$attributes=effectiveAttributes($pdo);
    $stage='independent_target';$target=independentTarget($pdo);
    $sqls=[
        'small'=>'SELECT 7 AS I FROM DUAL',
        'wide'=>"SELECT Q.V AS V,CAST(Q.V AS VARCHAR(128)) AS DM_SHADOW_0 FROM (SELECT CAST('9007199254740993' AS DECIMAL(20,0)) AS V FROM DUAL) Q",
        'two'=>'SELECT 1 AS I FROM DUAL UNION ALL SELECT 2 AS I FROM DUAL ORDER BY I',
        'empty'=>'SELECT 7 AS I FROM DUAL WHERE 1=0',
        'bound'=>'SELECT CAST(? AS DECIMAL(20,0)) AS V FROM DUAL',
    ];
    $query=function($name)use($pdo,$sqls){global $sqlLog;$sql=$sqls[$name];$sqlLog[]=hash('sha256',$sql);return $pdo->query($sql);};
    $stage='small';$stmt=$query('small');capSame(['i'=>7],$stmt->fetch());
    capSame($mode==='passthrough',$stmt instanceof PassThroughStatement);
    if($mode==='passthrough'){capSame('OLD_ONLY',$stmt->marker());}
    $stage='wide_native_red_and_text';$stmt=$query('wide');$raw=$stmt->fetch();
    capSame('double',gettype($raw['v']));capSame(true,(string)$raw['v']!=='9007199254740993');capSame('9007199254740993',$raw['dm_shadow_0']);
    $nativeRed=['original_type'=>gettype($raw['v']),'original_value'=>$raw['v'],'shadow_type'=>gettype($raw['dm_shadow_0']),'shadow_value'=>$raw['dm_shadow_0'],'irreversible_native_mismatch'=>true];
    $meta=[];for($i=0;$i<$stmt->columnCount();++$i){$all=$stmt->getColumnMeta($i);$meta[]=array_intersect_key($all,array_flip(['name','native_type','precision','scale']));}
    $stage='two_rows';capSame([['i'=>1],['i'=>2]],$query('two')->fetchAll());
    $stage='empty';capSame([],$query('empty')->fetchAll());
    $stage='prepare_reuse';$sqlLog[]=hash('sha256',$sqls['bound']);$stmt=$pdo->prepare($sqls['bound']);
    capSame($mode==='passthrough',$stmt instanceof PassThroughStatement);
    $stmt->bindValue(1,'7',PDO::PARAM_STR);capSame(true,$stmt->execute());capSame(7.0,$stmt->fetchColumn());capSame(false,$stmt->fetchColumn());
    capSame(true,$stmt->closeCursor());$stmt->bindValue(1,'-8',PDO::PARAM_STR);capSame(true,$stmt->execute());capSame(-8.0,$stmt->fetchColumn());
    $stmt2=$pdo->prepare($sqls['bound']);$sqlLog[]=hash('sha256',$sqls['bound']);$stmt2->execute(['9']);capSame(9.0,$stmt2->fetchColumn());
    $stmt->execute(['10']);capSame(10.0,$stmt->fetchColumn());
    echo json_encode(['status'=>'pass','mode'=>$mode,'stage'=>'complete','assertions'=>$n,'identity'=>$identity,'target'=>$target,'attributes'=>$attributes,'signatures'=>$signatures,'native_red'=>$nativeRed,'raw_metadata'=>$meta,'sql_sha256'=>$sqlLog,'business_reads'=>0,'dml'=>0,'ddl'=>0],JSON_UNESCAPED_SLASHES|JSON_PRESERVE_ZERO_FRACTION).PHP_EOL;
}catch(Throwable $e){echo json_encode(['status'=>'fail','stage'=>$stage,'assertions'=>$n,'class'=>get_class($e),'code'=>(string)$e->getCode(),'sql_sha256'=>$sqlLog,'dml'=>0,'ddl'=>0]).PHP_EOL;exit(1);}
