<?php

declare(strict_types=1);

// REVIEW DRAFT: three SELECT-only C HTTP routes, no synthetic DB writes.
if ((string)getenv('CDXPARCF_FINAL3_EXECUTE')!=='ROOT_APPROVED_EXACT_SHA') {
    fwrite(STDERR,"Review draft; execution disabled\n");
    exit(2);
}
$root='/tmp/zhct-dm-poc-20260928.fcpiiN/store';
$base='http://127.0.0.1:18080';
$pid=(string)getenv('POC_RUNTIME_PID');
if ((string)getenv('POC_DIALECT')!=='dm' || !ctype_digit($pid)) {
    fwrite(STDERR,"Approved C runtime required\n");
    exit(2);
}
function cdxFinalRows(PDO $db,string $sql,array $args=[]): array
{
    $stmt=$db->prepare($sql);
    $stmt->execute($args);
    return array_map(static function(array $row): array {
        return array_change_key_case($row,CASE_LOWER);
    },$stmt->fetchAll(PDO::FETCH_ASSOC));
}
function cdxFinalCount(PDO $db,string $sql,array $args=[]): int
{
    return (int)(cdxFinalRows($db,$sql,$args)[0]['n']??-1);
}
function cdxFinalContains($node,string $needle): bool
{
    if (is_string($node)) return $node===$needle;
    if (!is_array($node)) return false;
    foreach ($node as $value) {
        if (cdxFinalContains($value,$needle)) return true;
    }
    return false;
}
function cdxFinalFindName($node,string $needle): ?array
{
    if (!is_array($node)) return null;
    if (($node['name']??null)===$needle) return $node;
    foreach ($node as $value) {
        $found=cdxFinalFindName($value,$needle);
        if ($found!==null) return $found;
    }
    return null;
}
function cdxFinalPost(string $base,string $route,array $form): array
{
    $context=stream_context_create(['http'=>[
        'method'=>'POST',
        'header'=>"Content-Type: application/x-www-form-urlencoded\r\n",
        'content'=>http_build_query($form,'','&',PHP_QUERY_RFC3986),
        'timeout'=>20,'ignore_errors'=>true,
    ]]);
    $body=@file_get_contents($base.$route,false,$context);
    $headers=$http_response_header??[];
    preg_match('/HTTP\/\S+\s+(\d+)/',(string)($headers[0]??''),$match);
    $contentType='';
    foreach ($headers as $header) {
        if (stripos($header,'Content-Type:')===0) {
            $contentType=trim(substr($header,13));
        }
    }
    $json=is_string($body)?json_decode($body,true):null;
    return ['http_status'=>isset($match[1])?(int)$match[1]:0,
        'content_type'=>$contentType,
        'body_bytes'=>is_string($body)?strlen($body):null,
        'json'=>is_array($json)?$json:null];
}

$result=['lane'=>'C','cases'=>[],'business_dml'=>0,'permission_fixture_dml'=>0];
try {
    $cmdline=(string)file_get_contents('/proc/'.$pid.'/cmdline');
    if (strpos($cmdline,'127.0.0.1:18080')===false
        || strpos($cmdline,$root.'/public')===false) {
        throw new RuntimeException('C PID/port/docroot mismatch');
    }
    $expectedFiles=[
        $root.'/application/model/Restaurant.php'
            =>'7add87f50896ae3b94c00017f485eb3efaf473d5ee2f81c0c6120d4e85a287ab',
        $root.'/application/p/logic/Restaurant.php'
            =>'dbe6b5464c40ca6cb732fab45c96cd54c05834c071234aba11b5af48af89b871',
    ];
    foreach ($expectedFiles as $file=>$sha) {
        if (!is_file($file) || hash_file('sha256',$file)!==$sha) {
            throw new RuntimeException('Unapproved C Restaurant source copy');
        }
    }
    $boundary=json_decode((string)file_get_contents($base.'/__poc_boundary'),true);
    if (!is_array($boundary) || empty($boundary['external_stubs'])
        || empty($boundary['redis_isolated']) || !empty($boundary['real_queue'])) {
        throw new RuntimeException('C isolation boundary absent');
    }
    $env=array_fill_keys(['POC_HOST','POC_PORT','POC_SCHEMA',
        'POC_USER','POC_PASSWORD'],'');
    foreach (explode("\0",(string)file_get_contents('/proc/'.$pid.'/environ')) as $entry) {
        $pair=explode('=',$entry,2);
        if (count($pair)===2 && array_key_exists($pair[0],$env)) {
            $env[$pair[0]]=$pair[1];
        }
    }
    if ($env['POC_HOST']!=='127.0.0.1' || $env['POC_PORT']!=='5237'
        || strtoupper($env['POC_SCHEMA'])!=='ZHCT_APP'
        || strtoupper($env['POC_USER'])!=='ZHCT_APP'
        || $env['POC_PASSWORD']==='') {
        throw new RuntimeException('Unexpected C database');
    }
    $open=static function () use ($env): PDO {
        return new PDO('dm:host=127.0.0.1;port=5237;schema=ZHCT_APP',
            $env['POC_USER'],$env['POC_PASSWORD'],[
                PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE=>PDO::FETCH_ASSOC,
            ]);
    };
    $db=$open();
    if (strtoupper((string)$db->query(
        "SELECT SYS_CONTEXT('USERENV','CURRENT_SCHEMA') FROM DUAL")
        ->fetchColumn())!=='ZHCT_APP') {
        throw new RuntimeException('Wrong current schema');
    }
    $prefix='CDXPARCFRO%';
    foreach (['YDY_USER'=>'ACCOUNT','YDY_ROLE'=>'NAME',
        'YDY_USER_ROLE'=>'CREATE_BY','YDY_ROLE_MENU'=>'CREATE_BY'] as $table=>$column) {
        if (cdxFinalCount($db,'SELECT COUNT(*) N FROM '.$table
            .' WHERE '.$column.' LIKE ?',[$prefix])!==0) {
            throw new RuntimeException('Previous permission fixture not clean');
        }
    }
    $validSort='1,2,3,4,5,7,8,9,10,11,12,13,14,15,16,17,18,19,20,'
        .'21,22,23,24,25,26,27,28,29,34,35,36';
    $contextSql='SELECT DISTINCT d.UUID D_UUID,d.NAME D_NAME,'
        .' r.MENU_DATE R_DATE,r.RESTAURANT_ID R_ID'
        .' FROM YDY_DISHES d JOIN YDY_DISH c ON c.DISHES_UUID=d.UUID'
        .' JOIN YDY_FOODS_COMPOSITION f ON f.ID=c.COMPOSITION_ID'
        .' JOIN YDY_RECIPES r ON r.DISHES_UUID=d.UUID'
        .' WHERE d.STATUS=1 AND d.IS_DEL=1 AND d.IS_DELETE=0'
        .' AND d.STORE_ID=10001 AND d.WEIGHT>0 AND d.ENERGY>0'
        .' AND d.CATEGORY BETWEEN 1 AND 6 AND c.IS_DELETE=0'
        .' AND f.IS_DELETE=0 AND c.MINUTE_SORT IN ('.$validSort.')'
        .' AND r.MEAL_TIMES=1 AND EXISTS(SELECT 1 FROM YDY_DATE_MENU dm'
        .' WHERE dm.DISHES_UUID=r.DISHES_UUID'
        .' AND dm.MENU_DATE=r.MENU_DATE'
        .' AND dm.RESTAURANT_ID=r.RESTAURANT_ID'
        .' AND dm.MEAL_TIMES=1 AND dm.MEAL_TYPE=3)';
    $candidates=cdxFinalRows($db,$contextSql);
    $matches=[];
    foreach ($candidates as $row) {
        $uuid=(string)$row['d_uuid'];
        $day=substr((string)$row['r_date'],0,10);
        if (substr(hash('sha256',$uuid),0,12)==='2a23c2721fd0'
            && substr(hash('sha256',$day),0,12)==='fee7778c69b6') {
            $matches[]=['uuid'=>$uuid,'day'=>$day,
                'restaurant_id'=>(int)$row['r_id'],
                'name'=>(string)$row['d_name']];
        }
    }
    if (count($matches)!==1
        || !preg_match('/^\d{4}-\d{2}-\d{2}$/',$matches[0]['day'])
        || $matches[0]['restaurant_id']<=0 || $matches[0]['name']==='') {
        throw new RuntimeException('Original anonymous source changed/ambiguous');
    }
    $source=$matches[0];
    $result['source']=['uuid_sha12'=>'2a23c2721fd0',
        'date_sha12'=>'fee7778c69b6','existing_recipe_and_actual_menu'=>true];
    $before=cdxFinalCount($db,'SELECT COUNT(*) N FROM YDY_RECIPES r'
        .' WHERE r.DISHES_UUID=? AND r.MENU_DATE=?'
        .' AND r.RESTAURANT_ID=? AND r.MEAL_TIMES=1',
        [$source['uuid'],$source['day'],$source['restaurant_id']]);
    $beforeMenu=cdxFinalCount($db,'SELECT COUNT(*) N FROM YDY_DATE_MENU'
        .' WHERE DISHES_UUID=? AND MENU_DATE=? AND RESTAURANT_ID=?'
        .' AND MEAL_TIMES=1 AND MEAL_TYPE=3',
        [$source['uuid'],$source['day'],$source['restaurant_id']]);
    if ($before<=0 || $beforeMenu<=0) {
        throw new RuntimeException('Original natural relation no longer exists');
    }
    $cases=[
        ['/p/restaurant/nutrition',[
            'start_time'=>$source['day'],'end_time'=>$source['day'],
            'restaurant_id'=>$source['restaurant_id'],
            'meal_times'=>1,'status'=>1]],
        ['/p/restaurant/daypopularity',[
            'menu_date'=>$source['day'],'restaurant_id'=>$source['restaurant_id'],
            'meal_times'=>1]],
        ['/p/restaurant/morepopularity',[
            'start_time'=>$source['day'],'end_time'=>$source['day'],
            'restaurant_id'=>$source['restaurant_id'],'meal_times'=>1]],
    ];
    foreach ($cases as $case) {
        [$route,$form]=$case;
        $response=cdxFinalPost($base,$route,$form);
        $json=$response['json'];
        $data=is_array($json)?($json['data']??null):null;
        $found=false;
        if ($route==='/p/restaurant/daypopularity') {
            $index=is_array($data['x']??null)
                ? array_search($source['name'],$data['x'],true):false;
            $found=$index!==false
                && is_numeric($data['map_val'][$index]??null)
                && (float)$data['map_val'][$index]>0;
        } elseif ($route==='/p/restaurant/morepopularity') {
            $row=cdxFinalFindName($data['table']??[],$source['name']);
            $found=$row!==null && is_numeric($row['popularity']??null)
                && (float)$row['popularity']>0;
        } else {
            $found=cdxFinalContains($data,$source['name']);
        }
        $result['cases'][]=['route'=>$route,
            'status'=>$response['http_status']===200
                && is_array($json) && ($json['code']??null)===0 && $found
                ?'tested-pass':'tested-fail',
            'http_status'=>$response['http_status'],
            'content_type'=>$response['content_type'],
            'body_bytes'=>$response['body_bytes'],
            'business_code'=>is_array($json)?($json['code']??null):null,
            'target_in_response'=>$found,
            'data_types'=>is_array($data)?array_map('gettype',$data):[]];
    }
    $verify=$open();
    $after=cdxFinalCount($verify,'SELECT COUNT(*) N FROM YDY_RECIPES r'
        .' WHERE r.DISHES_UUID=? AND r.MENU_DATE=?'
        .' AND r.RESTAURANT_ID=? AND r.MEAL_TIMES=1',
        [$source['uuid'],$source['day'],$source['restaurant_id']]);
    $afterMenu=cdxFinalCount($verify,'SELECT COUNT(*) N FROM YDY_DATE_MENU'
        .' WHERE DISHES_UUID=? AND MENU_DATE=? AND RESTAURANT_ID=?'
        .' AND MEAL_TIMES=1 AND MEAL_TYPE=3',
        [$source['uuid'],$source['day'],$source['restaurant_id']]);
    $result['source']['recipe_count_unchanged']=$after===$before;
    $result['source']['actual_menu_count_unchanged']=$afterMenu===$beforeMenu;
    foreach (['YDY_USER'=>'ACCOUNT','YDY_ROLE'=>'NAME',
        'YDY_USER_ROLE'=>'CREATE_BY','YDY_ROLE_MENU'=>'CREATE_BY'] as $table=>$column) {
        if (cdxFinalCount($verify,'SELECT COUNT(*) N FROM '.$table
            .' WHERE '.$column.' LIKE ?',[$prefix])!==0) {
            throw new RuntimeException('Permission fixture appeared during read segment');
        }
    }
    $result['permission_fixture_cleanup']='not_needed_no_DML';
    echo json_encode($result,JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT).PHP_EOL;
    if (!$result['source']['recipe_count_unchanged']
        || !$result['source']['actual_menu_count_unchanged']) exit(1);
    foreach ($result['cases'] as $case) {
        if ($case['status']!=='tested-pass') exit(1);
    }
} catch (Throwable $error) {
    echo json_encode(['status'=>'preflight_or_postcheck_error',
        'class'=>get_class($error),'code'=>$error->getCode()]).PHP_EOL;
    exit(1);
}
