import struct
from decode_compute import decode,FORMAT,KEYS
valid=[0x41313030,1,160002,2,128000000,0x00f00000,1,80000,79000,2000,1000,3500,0,1,0,-49999,0.03,0.5,0.5,0.5]
r=decode(struct.pack(FORMAT,*valid));assert r['isolated_calculation_within_50us'] and not r['physical_execution_verified'] and not r['motor_run_permission']
count=1
for key,value in [('magic',0),('abi',2),('epoch',3),('status',1),('core_hz',16000000),('cpacr',0),('dwt_ctrl',0),('steps',0),('locked_steps',0),('observer_max_cycles',0),('foc_max_cycles',0),('combined_max_cycles',999),('calculation_budget_exceeded',1),('synthetic_source',0),('motor_run_permission',1),('last_rpm',float('nan')),('last_duty_a',1.1)]:
 sample=valid.copy();sample[KEYS.index(key)]=value
 try:decode(struct.pack(FORMAT,*sample))
 except ValueError:pass
 else:raise AssertionError(key)
 count+=1
for length in [0,79,81]:
 try:decode(bytes(length))
 except ValueError:pass
 else:raise AssertionError(length)
 count+=1
sample=valid.copy();sample[11]=7000;sample[12]=1;r=decode(struct.pack(FORMAT,*sample));assert not r['isolated_calculation_within_50us'] and not r['motor_run_permission'];count+=1
print(f'A100_DECODER_PASS {count} cases; fixtures synthetic, no target execution evidence')
