<?php
declare(strict_types=1);
namespace app\cores\database { class Dm {} }
namespace think {
 class Exception extends \Exception {}
 class Db { public static $counter=0; public static function name($table){return new class {public function where($x){return $this;} public function setInc($x){\think\Db::$counter++;return 1;}};} }
}
namespace app\model {
 class BaseModel { public $rows=[];public $dm=true;public function db($new=false){return $this;}public function getConnection(){return $this->dm?new \app\cores\database\Dm():new \stdClass();}public function __call($method,$args){return $this;}public function toArray(){return $this->rows;} }
}
namespace {
function guid(){return 'CDX-PRIVATE-NO-DATABASE';}function getImgFullPath($value){return $value;}function config($key){return $key==='database.type'&&($GLOBALS['plain_dm']??false)?'app\\cores\\database\\Dm':'mysql';}
$stage=$argv[1]??'original';if(!in_array($stage,['original','expanded'],true))exit(78);
$root=$stage==='expanded'?__DIR__.'/candidate-expanded/application':'/workspace/zhct/zhctproject/store/application';
require '/workspace/zhct/zhctproject/store/thinkphp/library/think/db/Expression.php';
require '/workspace/zhct/zhctproject/store/application/common/service/NutritionFloat82Write.php';
require __DIR__.'/candidate/NutritionPlainFloatWeight.php';
require $root.'/p/logic/Nutrition.php';require $root.'/m/logic/Nutrition.php';
foreach(['NutritionTemplateExt','NutritionSchemeExt','NutritionScheme']as $class)require $root.'/model/'.$class.'.php';
class FakeNutrition extends \app\model\BaseModel {
 public $row=[],$written=[]; public function read($uuid){return $this->row;}
 public function modify($uuid,$params){$this->written=$params;return 1;}
 public function add($params){$this->written=$params;return 1;}
 public function inquiryNutrition($where,$page,$size,$order,$field){return [$this->row];}
 public function inquiryCount($where){return 1;}
}
class FakeDictionary {public function where($x){return $this;}public function find(){return ['uuid'=>'exists'];}public function read($uuid){return ['uuid'=>$uuid];}public function inquiryColumn($where,$field){return ['CDX-category'];}}
class PrivateP extends \app\p\logic\Nutrition {
 public function __construct($model){$this->model=$model;$this->modelSet=new FakeDictionary();$this->modelNutritionCategory=new FakeDictionary();}
 public function updateSetNum($uuid_str=null,$set_uuid_str=null,$category_uuid_str=null){return ['code'=>0];}
}
class PrivateM extends \app\m\logic\Nutrition {public function __construct($model){$this->model=$model;}}
$wire=json_decode(file_get_contents(__DIR__.'/private/C/wire-plain-weight-1234567-info.json'),true);$row=array_values(array_filter($wire['after']['nutrition'],function($r){return $r['name']==='CDXNF11F5-candidate-product';}))[0];$pre=json_decode(file_get_contents(__DIR__.'/private/preflight-C.json'),true);$params=$pre['proposed_params'];$params['use_weight']='123.4567';$params['power']='12.345';$failed=[];$assertions=0;$check=static function($label,$ok)use(&$failed,&$assertions){$assertions++;if(!$ok)$failed[]=$label;};
foreach([true,false]as $dm){$GLOBALS['plain_dm']=$dm;$model=new FakeNutrition();$model->row=$row;$model->dm=$dm;$p=new PrivateP($model);$m=new PrivateM($model);
 foreach([['p',$p],['m',$m]]as [$name,$logic]){$result=$logic->update($params);$check($name.' update success',$result['code']===0);$expected=$dm?'CAST(123.45670318603516 AS REAL)':'123.4567';$check($name.' update plain mapping',(string)$model->written['use_weight']===$expected);$check($name.' update original supplier/is_own/set unaffected',$model->written['supplier']===$params['supplier']&&$model->written['set_uuid']===$params['set_uuid']&&$model->written['is_own']===1);$expectedMD=\app\common\service\NutritionFloat82Write::mapFields(['power'=>'12.345'],'nutrition',$dm)['power'];$check($name.' existing MD mapping unchanged',(string)$model->written['power']===(string)$expectedMD);
 $info=$logic->info($row['uuid']);$check($name.' info plain getter',$info['data']['use_weight']===($dm?123.457:123.4567));
 $list=$logic->lists([],1,1,[],['a.*','b.name as set_name']);$check($name.' fixed list plain getter',$list['data']['rows'][0]['use_weight']===($dm?123.457:123.4567));
 $dynamic=$logic->lists([],1,1,[],['SUM(a.use_weight) AS use_weight']);$check($name.' dynamic computed alias untouched',$dynamic['data']['rows'][0]['use_weight']===123.4567);
 }
 $added=$params;unset($added['uuid']);$result=$p->add($added);$check('p add success',$result['code']===0);$check('p add weight mapping',(string)$model->written['use_weight']===($dm?'CAST(123.45670318603516 AS REAL)':'123.4567'));$check('p add existing MD mapper',(string)$model->written['power']===(string)\app\common\service\NutritionFloat82Write::mapFields(['power'=>'12.345'],'nutrition',$dm)['power']);
 foreach(['NutritionTemplateExt','NutritionSchemeExt','NutritionScheme']as $name){$class='\\app\\model\\'.$name;$model=new $class();$model->rows=[['use_weight'=>123.4567,'power'=>12.345,'nullable'=>null],['use_weight'=>null,'power'=>1.0]];$model->dm=$dm;$rows=$name==='NutritionScheme'?$model->schemeRead('CDX',1):$model->inquiryAllInfo([]);$check($name.' fixed nutrition join getter',$rows[0]['use_weight']===($dm?123.457:123.4567));$check($name.' five MD and null preserve',$rows[0]['power']===12.345&&$rows[0]['nullable']===null&&$rows[1]['use_weight']===null);}
}
$r=['stage'=>$stage,'assertions'=>$assertions,'failures'=>$failed,'expected_red'=>$stage==='original','HTTP'=>0,'PDO'=>0,'DML'=>0,'fake_category_increment_calls'=>\think\Db::$counter,'limitation'=>'Pure real-logic/helper methods with fake ORM; UseTimeGroup, Scheme composition, Station post-write return only source/lint audited; no native acceptance implied'];
$f=__DIR__.'/private/expanded-tdd-'.$stage.'.json';file_put_contents($f,json_encode($r,JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));chmod($f,0600);echo json_encode($r),PHP_EOL;exit($failed?1:0);
}

