from pathlib import Path
import wave,io,struct,hashlib,json,base64,sys
p=Path(__file__).parent
samples=struct.pack('<8h',0,1000,-1000,2000,-2000,1000,-1000,0)
buffer=io.BytesIO()
with wave.open(buffer,'wb') as w:
 w.setnchannels(1);w.setsampwidth(2);w.setframerate(8000);w.writeframes(samples)
plain=buffer.getvalue()
junk=plain[:36]+b'JUNK'+struct.pack('<I',7)+b'fixture'+b'\x00'+plain[36:]
junk=junk[:4]+struct.pack('<I',len(junk)-8)+junk[8:]
fixtures={'plain.wav':plain,'junk.wav':junk}
result={'python':sys.version.split()[0],'fixtures':[]}
for name in ['plain.wav','junk.wav']:
 raw=fixtures[name];(p/name).write_bytes(raw)
 b64=base64.b64encode(raw).decode();(p/(name+'.b64.txt')).write_text(b64)
 chunks=[];pos=12
 while pos+8<=len(raw):
  tag=raw[pos:pos+4].decode('ascii');size=struct.unpack_from('<I',raw,pos+4)[0]
  chunks.append({'id':tag,'header_offset':pos,'payload_offset':pos+8,'size':size})
  pos+=8+size+(size%2)
 with wave.open(io.BytesIO(raw),'rb') as w:params={'channels':w.getnchannels(),'sample_width':w.getsampwidth(),'rate':w.getframerate(),'frames':w.getnframes()};pcm=w.readframes(w.getnframes())
 samples=list(struct.unpack('<'+'h'*(len(pcm)//2),pcm));wrong=raw[44:44+len(pcm)]
 result['fixtures'].append({'file':name,'bytes':len(raw),'base64_characters':len(b64),'riff_declared_size':struct.unpack_from('<I',raw,4)[0],'sha256':hashlib.sha256(raw).hexdigest(),'chunks':chunks,'params':params,'pcm_bytes':len(pcm),'pcm_sha256':hashlib.sha256(pcm).hexdigest(),'samples':samples,'wrong_fixed_44_samples':list(struct.unpack('<'+'h'*(len(wrong)//2),wrong)),'roundtrip_equal':base64.b64decode(b64,validate=True)==raw})
a,b=result['fixtures'];result['pcm_equal']=a['pcm_sha256']==b['pcm_sha256'];result['fixed44_equal']=a['wrong_fixed_44_samples']==b['wrong_fixed_44_samples']
(p/'raw-output.json').write_text(json.dumps(result,indent=2),encoding='utf8');print(json.dumps(result,indent=2))
