"""Read-only bounded BWF v0 bext sample-origin exercise; no trustworthy clock claim."""
import struct,json,hashlib
from fractions import Fraction
def chunk(tag,data):return tag+struct.pack('<I',len(data))+data+(b'\0'if len(data)%2 else b'')
def fixture(origin,rate=96000,with_bext=True):
    fmt=chunk(b'fmt ',struct.pack('<HHIIHH',1,1,rate,rate*2,2,16));bext=bytearray(602)
    bext[:15]=b'Authored silent';bext[256:269]=b'Opera fixture';bext[320:330]=b'2026-11-04';bext[330:338]=b'13:53:20'
    struct.pack_into('<IIH',bext,338,origin&0xffffffff,origin>>32,0)
    # v0 reserved bytes remain zero; no v2 UMID/loudness fields asserted.
    payload=b'WAVE'+fmt+(chunk(b'bext',bytes(bext))if with_bext else b'')+chunk(b'data',b'\0\0'*4801)
    return b'RIFF'+struct.pack('<I',len(payload))+payload
def inspect(raw):
    if len(raw)>1024*1024 or raw[:4]!=b'RIFF'or raw[8:12]!=b'WAVE'or struct.unpack_from('<I',raw,4)[0]+8!=len(raw):raise ValueError('bounded complete RIFF/WAVE only')
    p=12;rate=None;bext=None;pcm=None
    while p<len(raw):
        if p+8>len(raw):raise ValueError('truncated chunk')
        tag=raw[p:p+4];size=struct.unpack_from('<I',raw,p+4)[0];start=p+8;end=start+size
        if end+size%2>len(raw):raise ValueError('chunk exceeds actual file')
        if tag==b'fmt ':
            if rate is not None or size!=16:raise ValueError('one fmt16 required')
            form,ch,rate,br,align,bits=struct.unpack_from('<HHIIHH',raw,start)
            if (form,ch,align,bits)!=(1,1,2,16)or rate<=0 or br!=rate*2:raise ValueError('mono PCM16 subset')
        elif tag==b'bext':
            if bext is not None or size!=602:raise ValueError('one fixed v0 bext602 supported')
            low,high,version=struct.unpack_from('<IIH',raw,start+338)
            if version!=0:raise ValueError('bext version0 subset')
            bext={'low':low,'high':high,'sample_origin':(high<<32)|low,'version':version,'date_unverified':raw[start+320:start+330].decode('ascii'),'time_unverified':raw[start+330:start+338].decode('ascii')}
        elif tag==b'data':
            if pcm is not None:raise ValueError('one data chunk')
            pcm=raw[start:end]
        else:raise ValueError('chunk outside local subset')
        p=end+size%2
    if rate is None or pcm is None or len(pcm)%2:raise ValueError('missing fmt/data or partial frame')
    return {'rate':rate,'frames':len(pcm)//2,'bext':bext,'pcm_sha256':hashlib.sha256(pcm).hexdigest()}
def map_frame(meta,frame,expected_rate):
    if meta['rate']!=expected_rate:raise ValueError('expected rate differs from fmt; no invented conversion')
    if type(frame)is not int or not 0<=frame<meta['frames']:raise ValueError('existing frame index required')
    if meta['bext']is None:return None
    origin=meta['bext']['sample_origin'];sample=origin+frame
    return {'frame':frame,'relative_seconds':str(Fraction(frame,meta['rate'])),'sample_count_since_declared_midnight':sample,'seconds_since_declared_midnight':str(Fraction(sample,meta['rate'])),'utc_or_timezone_proven':False}
def demo():
    origin=4_800_000_000;raw=fixture(origin);before=hashlib.sha256(raw).hexdigest();one=inspect(raw);two=inspect(fixture(origin+96000));missing=inspect(fixture(0,with_bext=False))
    assert one['bext']['low']==505032704 and one['bext']['high']==1 and one['bext']['sample_origin']==origin
    points=[map_frame(one,i,96000)for i in [0,2400,4800]];assert [x['relative_seconds']for x in points]==['0','1/40','1/20']
    assert one['pcm_sha256']==two['pcm_sha256'] and map_frame(two,0,96000)['sample_count_since_declared_midnight']==origin+96000
    assert map_frame(missing,0,96000)is None and hashlib.sha256(raw).hexdigest()==before
    try:map_frame(one,0,48000)
    except ValueError as error:rate_error=str(error)
    else:raise AssertionError('rate mismatch accepted')
    return {'authored_silent_file_hex':raw.hex(),'one':one,'same_pcm_other_origin':two,'mapped_frames':points,'missing_bext':missing,'missing_origin_mapping':None,'rate_mismatch_rejected':rate_error,'original_hash_unchanged':True,'actual_file_bytes':len(raw),'real_audio_or_clock_validation':False,'scope':'Fixed v0 bext metadata and mono PCM16 fmt only. TimeReference declared sample count since midnight, not UTC/timezone or evidence of correct device clock. No day rollover inference; no audio/ASR execution.'}
if __name__=='__main__':print(json.dumps(demo(),indent=2))
