from pathlib import Path
import pcbnew,wx,json,xml.etree.ElementTree as E
app=wx.App(False);q=wx.LogNull();R=Path(__file__).resolve().parent;D=R/'cad';info=json.loads((R/'components.json').read_text());root=E.parse(D/'netlist.xml').getroot()
netmap={(x.get('ref'),x.get('pin')):n.get('name') for n in root.findall('./nets/net') for x in n.findall('node')};b=pcbnew.BOARD();nets={}
for name in sorted(set(netmap.values())):n=pcbnew.NETINFO_ITEM(b,name);b.Add(n);nets[name]=n
pos={'J1':(4,6),'U1':(20,12),'C1':(11.8,10.73)}
standard=Path('/Applications/KiCad/KiCad.app/Contents/SharedSupport/footprints')
for ref,typ,val,ident,_,_ in info['components']:
 lib,name=ident.split(':');dir=D/'Pressure_Adapter.pretty' if lib=='Pressure_Adapter' else standard/(lib+'.pretty')
 f=pcbnew.FootprintLoad(str(dir),name);assert f
 f.SetReference(ref);f.SetValue(val);
 if ref=="U1":f.SetField("Datasheet","https://cfsensor.com/wp-content/uploads/2026/09/XGZP6897D-Pressure-Sensor-V3.3.pdf")
 if ref=="C1":f.SetOrientationDegrees(180)
 f.SetFPID(pcbnew.LIB_ID(lib,name));f.SetPosition(pcbnew.VECTOR2I(*(pcbnew.FromMM(v) for v in pos[ref])))
 path=pcbnew.KIID_PATH();path.push_back(pcbnew.KIID(info['sheet_uuid']));path.push_back(pcbnew.KIID(info['instance'][ref]));f.SetPath(path);b.Add(f)
 for pad in f.Pads():pad.SetNet(nets[netmap[(ref,pad.GetNumber())]])
for a,z in [((0,0),(30,0)),((30,0),(30,25)),((30,25),(0,25)),((0,25),(0,0))]:
 sh=pcbnew.PCB_SHAPE(b);sh.SetShape(pcbnew.SHAPE_T_SEGMENT);sh.SetStart(pcbnew.VECTOR2I(*(pcbnew.FromMM(v) for v in a)));sh.SetEnd(pcbnew.VECTOR2I(*(pcbnew.FromMM(v) for v in z)));sh.SetWidth(pcbnew.FromMM(.05));sh.SetLayer(pcbnew.Edge_Cuts);b.Add(sh)
b.SetCopperLayerCount(2);pcbnew.SaveBoard(str(D/'vacuum_pressure_a114.kicad_pcb'),b)
print('unrouted panel saved')
