# Execute with FEMM5 native embeddedMicroPython from this extracted folder.
import os
def _exists(p):
    try:os.stat(p);return True
    except OSError:return False
if _exists('files/reproduce.py'):os.chdir('files')
elif '__file__' in globals() and '/' in __file__.replace('\\','/'):os.chdir(__file__.replace('\\','/').rsplit('/',1)[0])
import json,sys,math
assert sys.implementation.name=='micropython'
with open('key-cases.json') as f:cases=json.load(f)
output={'runtime':sys.version,'implementation':str(sys.implementation),'fresh_solves':[],'passed':True}

def count_conductors():
    n=0
    for j in range(1,int(mo_numelements())+1):
        e=mo_getelement(j)
        if int(e[6])==4 and complex(mo_getpointvalues(e[3],e[4])[3]).real>0:n+=1
    return n

for j,case in enumerate(cases):
    try:mo_close()
    except Exception:pass
    try:mi_close()
    except Exception:pass
    opendocument(case['model']);mi_saveas('replay-'+str(j)+'.fem');mi_analyze(1);mi_loadsolution()
    row={'model':case['model'],'circuits':{},'checks':[],'nodes':mo_numnodes(),'elements':mo_numelements()}
    if 'conductor_elements' in case:
        actual=count_conductors();expected=case['conductor_elements'];ok=actual==expected;row['checks'].append({'label':'conductor mesh elements','actual':actual,'expected':expected,'tolerance':0,'passed':ok});output['passed']=output['passed'] and ok
    for name,expected in case['circuits'].items():
        values=list(mo_getcircuitproperties(name));row['circuits'][name]=[[complex(v).real,complex(v).imag] for v in values]
        for k,label in [(0,'current_A'),(1,'voltage_V'),(2,'linkage_Wb')]:
            target=complex(expected[k][0],expected[k][1]) if isinstance(expected[k],list) else complex(expected[k]);actual=complex(values[k]);tol=max(1e-9,1e-5*abs(target));passed=abs(actual-target)<=tol;row['checks'].append({'label':name+':'+label,'error':abs(actual-target),'tolerance':tol,'passed':passed});output['passed']=output['passed'] and passed
    mo_clearblock();mo_groupselectblock();row['integrals']={str(k):[complex(mo_blockintegral(k)).real,complex(mo_blockintegral(k)).imag] for k in (2,3,4,6,17)};mo_clearblock()
    if 'magnet_probe' in case:
        spec=case['magnet_probe']
        for q in spec['extrema']:
            x,y=q['minimum_point_mm'];angle=math.atan2(y,x);sign=1 if q['pole']%2==0 else -1;vv=mo_getpointvalues(x,y);h=(complex(vv[1]).real*sign*math.cos(angle)+complex(vv[2]).real*sign*math.sin(angle)-spec['Br_T'])/(4*math.pi*1e-7*spec['mu']);err=abs(h-q['Hparallel_min_A_m']);passed=err<.01;row['checks'].append({'label':'physicalHparallel control pole'+str(q['pole']),'actual':h,'expected':q['Hparallel_min_A_m'],'error':err,'tolerance':.01,'passed':passed});output['passed']=output['passed'] and passed
    output['fresh_solves'].append(row)
    with open('replay-native-result.json','w') as f:json.dump(output,f)
# Original analytical example is included verbatim; it runs in this same real runtime.
with open('original-00.py') as f:exec(f.read(),globals())
with open('replay-native-result.json','w') as f:json.dump(output,f)
assert output['passed'],'A native key control differs from the supplied actual result'
with open('replay-result.json','w') as f:json.dump({'passed':output['passed'],'checks':[q for r in output['fresh_solves'] for q in r['checks']],'nativeFreshFieldCount':len(output['fresh_solves'])},f)
print('PORTABLE_NATIVE_CONTROLS',len(cases),output['passed'])
