"""Bounded educational RF64 subset. No large allocation, service or audio-quality test."""
import struct,hashlib,json
U32=0xffffffff
def chunk(tag,data):return tag+struct.pack('<I',len(data))+data+(b'\0'if len(data)%2 else b'')
def fixture(header_only=False):
    pcm=b'\0\0'*8;data_size=2**32+16 if header_only else len(pcm)
    fmt=chunk(b'fmt ',struct.pack('<HHIIHH',1,1,8000,16000,2,16));junk=chunk(b'JUNK',b'xyz')
    # RF64 header12 + ds64 chunk36 + fmt24 + JUNK12 + data header8 + payload.
    riff_size=12+36+len(fmt)+len(junk)+8+data_size-8
    ds=chunk(b'ds64',struct.pack('<QQQI',riff_size,data_size,data_size//2,0))
    return b'RF64'+struct.pack('<I',U32)+b'WAVE'+ds+fmt+junk+b'data'+struct.pack('<I',U32)+(b''if header_only else pcm)
def ds64_header(raw):
    if len(raw)<48 or raw[:4]!=b'RF64'or raw[8:12]!=b'WAVE'or struct.unpack_from('<I',raw,4)[0]!=U32:raise ValueError('RF64/WAVE with RIFF sentinel required')
    if raw[12:16]!=b'ds64'or struct.unpack_from('<I',raw,16)[0]!=28:raise ValueError('first mandatory ds64 payload28 only; table unsupported')
    riff,data,samples,table=struct.unpack_from('<QQQI',raw,20)
    if table:raise ValueError('optional size table not implemented')
    return {'riff_size_64':riff,'data_size_64':data,'sample_count_64':samples}
def inspect(raw):
    if len(raw)>1024*1024:raise ValueError('bounded small fixture only')
    header=ds64_header(raw)
    if header['riff_size_64']+8!=len(raw):raise ValueError('declared RIFF length differs from actual buffer')
    pos=48;fmt=None;data=None;trace=[]
    while pos<len(raw):
        if pos+8>len(raw):raise ValueError('truncated chunk header')
        tag=raw[pos:pos+4];size32=struct.unpack_from('<I',raw,pos+4)[0]
        if tag==b'data':
            if size32!=U32 or data is not None:raise ValueError('one data chunk with sentinel required')
            size=header['data_size_64']
        else:
            if size32==U32:raise ValueError('non-data size table not implemented')
            size=size32
        start=pos+8;end=start+size;padded=end+size%2
        if padded>len(raw):raise ValueError('bounded payload/pad exceeds actual buffer')
        trace.append({'tag':tag.decode('ascii'),'size32':size32,'resolved_size':size,'offset':start,'pad_bytes':size%2})
        if tag==b'fmt ':
            if fmt is not None or size!=16:raise ValueError('one plain PCM fmt16 required')
            tagfmt,ch,rate,byte_rate,align,bits=struct.unpack_from('<HHIIHH',raw,start)
            if (tagfmt,ch,align,bits)!=(1,1,2,16)or byte_rate!=rate*align or rate<=0:raise ValueError('mono PCM16 subset only')
            fmt={'rate':rate,'block_align':align}
        elif tag==b'data':data=raw[start:end]
        elif tag!=b'JUNK':raise ValueError('unknown chunk outside declared subset')
        pos=padded
    if fmt is None or data is None or len(data)%fmt['block_align']:raise ValueError('missing fmt/data or partial frame')
    frames=len(data)//fmt['block_align']
    if frames!=header['sample_count_64']:raise ValueError('sampleCount and PCM frames differ')
    return {**header,**fmt,'frames':frames,'actual_bytes':len(raw),'pcm_sha256':hashlib.sha256(data).hexdigest(),'trace':trace}
def rejected(raw):
    try:inspect(raw)
    except ValueError as error:return str(error)
    raise AssertionError('invalid fixture accepted')
def demo():
    raw=fixture();out=inspect(raw);assert out['frames']==8 and out['data_size_64']==16 and out['riff_size_64']+8==len(raw)
    assert any(x['tag']=='JUNK'and x['pad_bytes']==1 for x in out['trace'])
    missing=bytearray(raw);missing[12:16]=b'JUNK'
    sentinel=bytearray(raw);sentinel[4:8]=struct.pack('<I',len(raw)-8)
    wrong_data=bytearray(raw);data_header=next(x['offset']-8 for x in out['trace']if x['tag']=='data');struct.pack_into('<I',wrong_data,data_header+4,16)
    mismatch=bytearray(raw);struct.pack_into('<Q',mismatch,20,len(raw)-7)
    large=fixture(True);header=ds64_header(large);assert header['data_size_64']==2**32+16 and len(large)<1024
    return {'small_complete_authored_rf64_hex':raw.hex(),'small':out,'invalid_cases':{'missing_ds64':rejected(missing),'wrong_riff_sentinel':rejected(sentinel),'wrong_data_sentinel':rejected(wrong_data),'length_mismatch':rejected(mismatch),'truncated_payload':rejected(raw[:-1])},'header_only_large_declared':{'bytes_actually_created':len(large),'header':header,'complete_audio_file':False,'strict_inspection_rejection':rejected(large)},'scope':'RF64 subset: mandatory ds64 table0, one fmt16 mono PCM16, optional JUNK and one data sentinel. No BW64, size tables, compressed audio, big file creation, audio playback or product support proven.'}
if __name__=='__main__':print(json.dumps(demo(),indent=2))
