from pathlib import Path
import shutil,re,json,hashlib
P=Path(__file__).resolve().parent;A=P.parent/'drill_cap_footprints_A90'
for x in ['drill_motor_a85_cutoff.kicad_sch','drill_motor_a85_cutoff.kicad_pro','Project.kicad_sym','sym-lib-table','fp-lib-table']:shutil.copyfile(A/x,P/x)
shutil.copytree(A/'MotorStage.pretty',P/'MotorStage.pretty',dirs_exist_ok=True)
shutil.copyfile(A/'drill_motor_a85_cutoff.kicad_pcb',P/'baseline-A90.kicad_pcb');shutil.copyfile(A/'drill_motor_a85_cutoff.kicad_pro',P/'baseline-A90.kicad_pro');shutil.copyfile(A/'netlist-A90.xml',P/'baseline-netlist-A90.xml')
def end(s,i):
 depth=0;q=False;esc=False
 for n in range(i,len(s)):
  c=s[n]
  if q:
   if esc:esc=False
   elif c=='\\':esc=True
   elif c=='"':q=False
  elif c=='"':q=True
  elif c=='(':depth+=1
  elif c==')':
   depth-=1
   if not depth:return n+1
 raise ValueError('unbalanced')
names={'PinHeader_2x10_P2.54mm_Vertical':'WE_61302021121_2x10_P2.54_Drill1.2','PinHeader_1x02_P2.54mm_Vertical':'WE_61300211121_1x02_P2.54_Drill1.2','PinHeader_1x03_P2.54mm_Vertical':'WE_61300311121_1x03_P2.54_Drill1.2'}
s=(P/'baseline-A90.kicad_pcb').read_text();edits=[];holes=0
for m in re.finditer(r'\(footprint "Connector_PinHeader_2.54mm:([^"]+)"',s):
 i=m.start();j=end(s,i);t=s[i:j];ref=re.search(r'\(property "Reference" "([^"]+)"',t).group(1);assert ref in ['J1','J2','J3','J4','J5'];old=m.group(1);assert old in names
 holes+=t.count('(drill 1)');t=t.replace('Connector_PinHeader_2.54mm:'+old,'MotorStage:'+names[old]).replace('(drill 1)','(drill 1.2)');edits.append((i,j,t,ref))
assert len(edits)==5 and holes==29
for i,j,t,ref in reversed(edits):s=s[:i]+t+s[j:]
(P/'drill_motor_a85_cutoff.kicad_pcb').write_text(s)
f=P/'drill_motor_a85_cutoff.kicad_sch';s=f.read_text()
for old,new in names.items():s=s.replace('Connector_PinHeader_2.54mm:'+old,'MotorStage:'+new)
s=s.replace('A90-CAP-LAND-CANDIDATE','A92-HEADER-HOLE-CANDIDATE').replace('A90 DRILL MOTOR','A92 DRILL MOTOR');f.write_text(s)
for old,new in names.items():
 f=Path('/Applications/KiCad/KiCad.app/Contents/SharedSupport/footprints/Connector_PinHeader_2.54mm.pretty')/(old+'.kicad_mod');s=f.read_text().replace(old,new).replace('(drill 1)','(drill 1.2)')
 while '(model ' in s:
  i=s.index('(model ');j=end(s,i);s=s[:i]+s[j:]
 s=re.sub(r'\(descr "[^"]*"\)', '(descr "WE engineering header candidate; nominal plated hole 1.2mm; target finished hole 1.20+/-0.03mm requires factory acceptance; not released")',s,count=1)
 (P/'MotorStage.pretty'/(new+'.kicad_mod')).write_text(s)
(P/'patch-receipt-A92.json').write_text(json.dumps({'changed_refs':[e[3] for e in edits],'changed_holes':holes,'old_nominal_mm':1,'new_nominal_mm':1.2,'target_finished_hole_mm':1.2,'target_finished_hole_tolerance_mm':0.03,'factory_capability_confirmed':False,'source_baseline_sha256':hashlib.sha256((P/'baseline-A90.kicad_pcb').read_bytes()).hexdigest()},indent=2)+'\n');print('patched',holes,'holes')
