"""Audit current native front datums against an explicitly earlier factory drawing.

No geometry, placement or 1500 factory specification is changed by this audit.
"""
from pathlib import Path
import json,hashlib,subprocess,math
import cadquery as cq
ROOT=Path(__file__).resolve().parent;BASE='b9cdcf85';S=2032/2.4
body_path=ROOT.parent/'body-data.json';body=json.loads(body_path.read_text());pl=body['native_front_structure_placement'];assert pl['native_anchor_mm']==pl['body_anchor_units']==[0,0,0]
d=json.loads((ROOT/'front-pickup-channel-reference.json').read_text());a=cq.Assembly.importStep(str(ROOT/'front-pickup-channel-reference.step'));shapes={n:o.obj for n,o in a.objects.items()if o.obj is not None}
wish=json.loads((ROOT/'wishbone-shell-reference.json').read_text());brackets=d['lower_pickup_channel_revision']['brackets'];probes=[];axes={}
for side in ['left','right']:
 shape=shapes['front_structure_'+side+'_lower_pickup_ear_comparison'];assert shape.isValid()
 for row in brackets[side]:
  x,y,z=row['pivot_axis_center_mm'];axes[(side,row['position'])]=[x,y,z]
  assert any(all(abs(x1*S-x2)<1e-8 for x1,x2 in zip(p,[x,y,z]))for p in wish['nodes'][side]['inner_centers_units'])
  # Positive-Z receiver sheet, retaining the existing node/access-side convention.
  cz=z+.03*S;axis=cq.Vector(0,0,1);p=cq.Vector(x,y,cz)
  void=shape.intersect(cq.Solid.makeCylinder(6.2,8,p-axis*4,axis)).Volume();assert void<1e-6
  material=shape.intersect(cq.Solid.makeCylinder(.3,8,p+cq.Vector(7,0,0)-axis*4,axis)).Volume();assert material>.1
  probes.append(dict(side=side,position=row['position'],axis_center_body_mm=[x,y,z],receiver_void_mm3=void,adjacent_wall_material_mm3=material))
widths={pos:abs(axes[('left',pos)][0]-axes[('right',pos)][0])for pos in ['front','rear']};assert all(abs(v-609.6)<1e-8 for v in widths.values())
sections=[]
for z in [.4*S,.7*S,1.1*S]:
 spans={}
 for side in ['left','right']:
  shape=shapes['front_structure_'+side+'_open_rail_reference'];slice_=shape.intersect(cq.Solid.makeBox(1000,1,1,(-500,.30*S-.5,z-.5)));assert slice_.Volume()>0
  bb=slice_.BoundingBox();spans[side]=[bb.xmin,bb.xmax]
 gap=spans['left'][0]-spans['right'][1];assert abs(gap-546.1)<1e-6
 sections.append(dict(y_body_mm=.30*S,z_body_mm=z,rail_spans_x_mm=spans,inner_face_gap_mm=gap))
refs=[dict(label='A–A: front inner-pivot pair',cad_mm=widths['front'],earlier_printed_metric_mm=465.2,earlier_read_inch=18+3/8),dict(label='B–B: rear inner-pivot pair',cad_mm=widths['rear'],earlier_printed_metric_mm=465.2,earlier_read_inch=18+3/8),dict(label='C–C: inside frame side-members',cad_mm=sections[0]['inner_face_gap_mm'],earlier_printed_metric_mm=279.4,earlier_read_inch=11)]
for ref in refs:
 ref['arithmetic_difference_from_earlier_metric_mm']=ref['cad_mm']-ref['earlier_printed_metric_mm'];ref['inch_conversion_mm']=ref['earlier_read_inch']*25.4;ref['printed_unit_disagreement_mm']=ref['inch_conversion_mm']-ref['earlier_printed_metric_mm'];ref['classification']='Earlier-model comparison only; not a verified1500 nominal, fitted error or repair dimension.'
held={}
for stem in ['front-pickup-channel-reference','wishbone-shell-reference','front-power-support-reference','front-footwell-reference','steering-rack-reference']:
 for ext in ['.json','.step']:
  p=ROOT/(stem+ext);raw=p.read_bytes();assert raw==subprocess.check_output(['git','show',BASE+':cars/1975-mg-midget/cad/'+p.name]);held[p.name]=hashlib.sha256(raw).hexdigest()
assert body_path.read_bytes()==subprocess.check_output(['git','show',BASE+':cars/1975-mg-midget/body-data.json'])
report=dict(schema='front-frame-datum-review-v1',baseline_commit=BASE,classification='New primary-source and native-geometry evidence; no geometry or fitted registration correction applied.',geometry_changed=False,owner_dimensions_applied=False,source=dict(url='https://www.spridgetguru.com/AKD4021B/AKD4021BRRa.pdf#page=18',publication='AKD4021B, SectionR.16, printedR.18, Issue3.65317',pdf_sha256=hashlib.sha256(Path('/private/tmp/midget-akd4021b-body.pdf').read_bytes()).hexdigest(),model_coverage='Footer names SpriteMkII/III and MidgetMkI/II. Diagram shows an earlier rear-spring arrangement.1500 applicability is unproven.',warning='Read directly from original PDF, not search-result OCR. A/B appear as18⅜in but print465.2mm; D prints37½in/952.1mm. Those unit pairs disagree. No silently corrected unit or averaged dimension is applied.'),comparisons=refs,pivot_receiver_native_probes=probes,rail_native_section_checks=sections,held_neighbor_sources_sha256=held,body_register_sha256=hashlib.sha256(body_path.read_bytes()).hexdigest(),global_registration=dict(engine_frame_held=True,body_frame_held=True,wheel_and_suspension_frames_held=True,fitted_engine_body_transform_established=False,reason='A horizontal width drawing does not establish Y/Z station identity,engine pose,loaded suspension or owner-car datum coordinates.'),evidence_lookup=dict(repository_export_found=False,attachment_export_found=False,scope='Car-related repository/attachment filenames and existing measurement modules/templates reviewed; not a claim about all private files or unsaved browser storage.',existing_owner_datum_path_request_pending=True,existing_manual_path_request_pending=True),manual_access=dict(cover_verified='Public Teil1 scan title is AKM4071/B;cover says it incorporates earlier manuals includingAKM3267 and covers US/Canada/UK versions.',part1=dict(url='https://www.spridgets.de/downloads/Midget%201500%20WH%20Teil%201.pdf',pages=38,sha256=hashlib.sha256(Path('/private/tmp/midget-workshop-part1.pdf').read_bytes()).hexdigest()),part3=dict(url='https://www.spridgets.de/downloads/Midget%201500%20WH%20Teil%203.pdf',pages=35,starts_printed_page=74,sha256=hashlib.sha256(Path('/private/tmp/midget-workshop-part3.pdf').read_bytes()).hexdigest()),unavailable_guessed_part_numbers=[4,5,6],unavailable_response='HTTP403;not evidence that those chapters are absent from the publication. No access control was bypassed.',needed='Applicable1500horizontal/vertical alignment drawings around printed186–187;original page/point definitions and both unit columns need direct review.'),rejected_leads=[dict(source='https://mgcar.fans/kb/mgb/1976-technical-service-bulletins/',item='76-C-2',reason='Index explicitly applies to1975/76MGB,not Midget;not used for model dimensions.'),dict(source='https://spriteparts.com.au/shop/brochures.html',item='Sprite/Midget horizontal alignment sheet',reason='Listing does not establish1500applicability or expose a dimensioned1500original;not purchased or applied.')],next_action='Verify the actual1500drawing/point definitions and resolve unit conflicts before a coordinated change across rails,pickups,wishbones and connected supports. Do not move only the engine or individual brackets to erase overlaps,or reuse this comparison as an owner survey.',limits='This audit exposes a major unsupported transverse construction;it does not independently prove which current dimension is wrong for the actual car. No diagonals,global scale,Y/Zdatum,repair alignment,loaded clearance,safe support or replacement path is established.')
(ROOT/'front-frame-datum-review.json').write_text(json.dumps(report,indent=2)+'\n');print(json.dumps(dict(comparisons=refs,native_receiver_probes=len(probes),rail_section_checks=len(sections),held_source_files=len(held),geometry_changed=False)))
