from pathlib import Path
import re,sys,uuid,shutil,json
B=Path(__file__).resolve().parent;R=B/'lamp_frontend_pair_A43';D=R/'power_board';D.mkdir(parents=True,exist_ok=True)
sys.path.insert(0,str(B/'parity_metadata_closure_A22'));from prepare_candidates import forms,run;from align_and_verify import footprint_rows
S=B/'r13_candidate_A24/lamp_a3_r13_candidate';OLD='lamp_buck_lmr51450_a3_r13';N='lamp_buck_lmr51450_a4_frontend';uid=lambda:str(uuid.uuid4())
for ext in ['kicad_pro']:shutil.copy2(S/(OLD+'.'+ext),D/(N+'.'+ext))
shutil.copytree(S/'Lamp_Power.pretty',D/'Lamp_Power.pretty',dirs_exist_ok=True)
for name in ['Project.kicad_sym','sym-lib-table','fp-lib-table']:shutil.copy2(S/name,D/name)
s=(S/(OLD+'.kicad_sch')).read_text();s=s.replace('(project "'+OLD+'"','(project "'+N+'"')
original=next(f for _,_,f in forms(s,'symbol') if '(property "Reference" "C11"' in f)
c=original.replace('C11','C14').replace('100nF V monitor filter','100n X7R 16V INA VS bypass');c=re.sub(r'\(uuid "[^"]+"\)',lambda m:'(uuid "'+uid()+'")',c)
new_uuid=re.search(r'\(uuid "([^"]+)"',c)[1]
c=re.sub(r'\(at ([\d.-]+) ([\d.-]+) 0\)',lambda m:f'(at {float(m[1])+74.93:.2f} {float(m[2]):.2f} 0)',c)
add=c
for y,net in [(240.03,'CTRL_3V3'),(250.19,'GND')]:
 add+=f'(wire (pts (xy 500.38 {y}) (xy 508 {y})) (stroke (width 0) (type default)) (uuid "{uid()}"))'
 add+=f'(label "{net}" (at 508 {y} 0) (effects (font (size 1 1)) (justify left bottom)) (uuid "{uid()}"))'
s=s.rstrip()[:-1]+add+')\n';sch=D/(N+'.kicad_sch');sch.write_text(s)
t=(S/(OLD+'.kicad_pcb')).read_text();c=next(f for _,_,f,ref,_ in footprint_rows(t) if ref=='C11')
c=re.sub(r'\(uuid "[^"]+"\)',lambda m:'(uuid "'+uid()+'")',c).replace('"C11"','"C14"').replace('100nF V monitor filter','100n X7R 16V INA VS bypass')
a,b,_=next(forms(c,'at'));c=c[:a]+'(at 86.3 32.8)'+c[b:]
for a,b,pad in reversed(list(forms(c,'pad'))):
 pin=re.match(r'\(pad "([^"]+)"',pad)[1];net='/CTRL_3V3' if pin=='1' else '/GND'
 pad=re.sub(r'\(net "[^"]+"\)', '(net "'+net+'")',pad);c=c[:a]+pad+c[b:]
# Match schematic UUID path; preserve the existing project root path.
c=re.sub(r'\(path "([^" ]+)/[^/" ]+"\)',lambda m:'(path "'+m[1]+'/'+new_uuid+'")',c)
add=c
for points,layer,net in [([(82.1375,33.05),(82.625,32.9)],'F.Cu','/CTRL_3V3'), ([(82.625,32.9),(82.625,32.8),(85.525,32.8)],'B.Cu','/CTRL_3V3'), ([(87.075,32.8),(87.5,32.1)],'F.Cu','/GND')]:
 for a,b in zip(points,points[1:]):
  add+=f'(segment (start {a[0]} {a[1]}) (end {b[0]} {b[1]}) (width 0.25) (layer "{layer}") (net "{net}") (uuid "{uid()}"))'
for x,y,net in [(82.625,32.9,'/CTRL_3V3'),(85.525,32.8,'/CTRL_3V3'),(87.5,32.1,'/GND'),(78.8359,34,'/GND')]:
 add+=f'(via (at {x} {y}) (size 0.65) (drill 0.3) (layers "F.Cu" "B.Cu") (net "{net}") (uuid "{uid()}"))'
t=t.rstrip()[:-1]+add+')\n';pcb=D/(N+'.kicad_pcb');pcb.write_text(t)
run(['sch','export','netlist','--format','kicadxml','--output',str(D/'netlist.xml'),str(sch)],D/'netlist.log')
run(['sch','erc','--severity-all','--format','json','--output',str(D/'erc.json'),str(sch)],D/'erc.log')
run(['pcb','drc','--refill-zones','--save-board','--schematic-parity','--format','json','--output',str(D/'drc.json'),str(pcb)],D/'drc.log')
j=json.loads((D/'drc.json').read_text());print({k:len(j[k]) for k in ['violations','unconnected_items','schematic_parity']});print(j['violations'][:8]);print(j['schematic_parity'][:4])
