from pathlib import Path
import sys,re,uuid,json,shutil
R=Path(__file__).resolve().parent;B=R.parent;sys.path.insert(0,str(B/'parity_metadata_closure_A22'));from prepare_candidates import forms,run
from align_and_verify import footprint_rows,netlist
D=R/'board';D.mkdir(exist_ok=True);N='lamp_safety_evt_a3_IR_PCB';S=B/'lamp_IR_hardware_A38'
for ext in ['kicad_sch','kicad_pro']:
 shutil.copy2(S/('IR_schematic_candidate/lamp_safety_evt_a2_IR_interface.'+ext),D/(N+'.'+ext))
p=D/(N+'.kicad_sch');p.write_text(p.read_text().replace('(project "lamp_safety_evt_a2_IR_interface"','(project "'+N+'"'))
for f in ['Project.kicad_sym','sym-lib-table']:shutil.copy2(S/'IR_schematic_candidate'/f,D/f)
run(['sch','export','netlist','--format','kicadxml','--output',str(D/'netlist.xml'),str(p)],D/'netlist.log')
fps,pins=netlist(D/'netlist.xml');s=(S/'paired/lamp_safety_evt_a1_metadata.kicad_pcb').read_text();orig=s
rows={ref:f for _,_,f,ref,_ in footprint_rows(s)}
for st,en,f,ref,_ in footprint_rows(s):
 if ref=='U1':
  u=f
  for a,b,pad in forms(u,'pad'):
   if pad.startswith('(pad "3"'):
    z=re.sub(r'\(net "[^"]+"\)', '(net "/IR_HAND")',pad);assert z!=pad;u=u[:a]+z+u[b:];break
  s=s[:st]+u+s[en:];break
uid=lambda:str(uuid.uuid4())
def fp(source,ref,value,x,y):
 f=source
 f=re.sub(r'\(uuid "[^"]+"\)',lambda m:'(uuid "'+uid()+'")',f)
 f=re.sub(r'\(property\s+"Reference"\s+"[^"]+"',lambda m:'(property "Reference" "'+ref+'"',f,count=1)
 f=re.sub(r'\(property\s+"Value"\s+"[^"]+"',lambda m:'(property "Value" "'+value+'"',f,count=1)
 a,b,_=next(forms(f,'at'));f=f[:a]+f'(at {x:.4f} {y:.4f})'+f[b:]
 for a,b,pad in reversed(list(forms(f,'pad'))):
  pin=re.match(r'\(pad "([^"]+)"',pad)[1];name=pins[(ref,pin)]
  z=re.sub(r'\(net "[^"]+"\)','',pad);z=z[:-1]+'(net '+json.dumps(name)+'))';f=f[:a]+z+f[b:]
 f=re.sub(r'^(\(footprint\s+)"[^"]+"',lambda m:m.group(1)+json.dumps(fps[ref]),f,count=1)
 return f
adds=[fp(rows['R18'],'R20','1k 1%',63,46),fp(rows['R18'],'R21','47k 1%',63,49.2),fp(rows['C1'],'C8','10n X7R 16V',34.3,15.5)]
lib=Path('/Applications/KiCad/KiCad.app/Contents/SharedSupport/footprints/Connector_PinHeader_2.54mm.pretty/PinHeader_1x03_P2.54mm_Vertical.kicad_mod').read_text()
lib=re.sub(r'\(version \d+\)|\(generator [^)]*\)|\(generator_version [^)]*\)','',lib)
# Library footprints have no board placement; insert before the first property.
lib=lib.replace('(layer "F.Cu")','(layer "F.Cu")\n(at 67.0000 44.0000)\n(uuid "'+uid()+'")',1)
adds.append(fp(lib,'J6','IR SENSOR 3V3 ACTIVE HIGH',67,44))
s=s.rstrip()[:-1]+'\n'+'\n'.join(adds)+'\n)\n';P=D/(N+'.kicad_pcb');P.write_text(s)
run(['pcb','drc','--refill-zones','--save-board','--schematic-parity','--format','json','--output',str(D/'initial_drc.json'),str(P)],D/'initial_drc.log')
j=json.loads((D/'initial_drc.json').read_text());print({k:len(j[k]) for k in ['violations','unconnected_items','schematic_parity']});print(j['violations'][:2])
(R/'original_board.txt').write_text(orig)
