from pathlib import Path
import json,struct,hashlib,csv
root=Path(__file__).resolve().parent;source=json.loads((root/'local-results.json').read_text());rows=[]
for expected in source['rows']:
 b=(root/expected['midiFile']).read_bytes();assert b[:4]==b'MThd' and b[14:18]==b'MTrk'
 assert struct.unpack_from('>HHH',b,8)==(0,1,480);assert struct.unpack_from('>I',b,18)[0]==len(b)-22
 i=22;status=None;tick=0;on=[];off=[];meta=[]
 def vlq():
  global i
  n=0
  while True:
   x=b[i];i+=1;n=(n<<7)|(x&127)
   if x<128:return n
 while i<len(b):
  tick+=vlq()
  if b[i]>=128:status=b[i];i+=1
  if status==255:
   t=b[i];i+=1;n=vlq();data=b[i:i+n];i+=n;meta.append(t)
   if t==47:break
  else:
   p,v=b[i:i+2];i+=2
   if status&240==144 and v:on.append({'pitch':p,'tick':tick,'velocity':v})
   elif status&240==128 or (status&240==144 and not v):off.append({'pitch':p,'tick':tick})
 assert [n['pitch'] for n in on]==[n['pitch'] for n in expected['notes']]
 assert len(on)==len(off) and [n['pitch'] for n in on]==[n['pitch'] for n in off]
 exact=set(n['pitch'] for n in on)&set(source['targetPitches'])
 assert len(exact)==expected['targetPitchSetCoverage']
 rows.append({'file':expected['midiFile'],'name':expected['name'],'mode':expected['mode'],'bytes':len(b),'sha256':hashlib.sha256(b).hexdigest(),'noteOns':on,'noteOffs':off,'metaTypes':meta,'targetPitchSetCoverage':len(exact)})
mix=[r for r in rows if r['name']=='mix'];bass=[r for r in rows if r['name']=='known-bass']
assert all(r['targetPitchSetCoverage']==0 and [n['pitch'] for n in r['noteOns']]==[48] for r in mix)
assert len({r['sha256'] for r in mix+bass})==1
assert all(r['targetPitchSetCoverage']==3 and [n['pitch'] for n in r['noteOns']]==[72,76,79,83] for r in rows if r['name']=='known-melody')
(root/'independent-results.json').write_text(json.dumps({'result':'PASS','method':'Independent Python SMF chunk/VLQ event reader; compare exact pitch identity against known intended part, not note count alone','rows':rows},indent=2),encoding='utf-8')
with (root/'results.csv').open('w',newline='',encoding='utf-8') as f:
 w=csv.writer(f);w.writerow(['input','mode','pitches','target_pitch_set_coverage_of_4','MIDI_bytes','SHA256'])
 for r in rows:w.writerow([r['name'],r['mode'],' '.join(str(n['pitch']) for n in r['noteOns']),r['targetPitchSetCoverage'],r['bytes'],r['sha256']])
print(json.dumps({'result':'PASS','midiFiles':len(rows),'mixtureModes':3,'mixtureTargetPitches':0,'isolatedTargetPitches':3,'isolatedLastPitchError':'84 became83','mixAndBassByteIdentical':True}))
