#!/usr/bin/env python3
"""Dump raw MIDI track bytes for debugging."""
import os, struct

path = '/root/.openclaw/media/inbound/laboom.mp3-midi-drums---addefb4a-e5d1-44db-af92-8916eff1662b.mid'

with open(path, 'rb') as f:
    data = f.read()

# Header
fmt, ntracks = struct.unpack('>HH', data[8:12])
division = struct.unpack('>h', data[12:14])[0]
print(f"Format={fmt} Tracks={ntracks} Div={division}\n")

offset = 14
for t in range(ntracks):
    tc = data[offset:offset+4]
    ts = struct.unpack('>I', data[offset+4:offset+8])[0]
    track_data = data[offset+8:offset+8+ts]
    
    print(f"{'='*60}")
    print(f"Track {t}: {ts} bytes, first 100 raw hex:")
    print('  ', ' '.join(f'{b:02x}' for b in track_data[:100]))
    print()
    
    # Parse events manually
    i = 0
    events_count = 0
    notes_found = []
    
    while i < len(track_data):
        delta = 0
        b = track_data[i]; i += 1
        while b & 0x80:
            delta = (delta << 7) | (b & 0x7F)
            if i >= len(track_data): break
            b = track_data[i]; i += 1
        delta = (delta << 7) | (b & 0x7F)
        
        if i >= len(track_data):
            print(f"  [event {events_count}] delta={delta} END of track")
            break
        
        byte = track_data[i]
        event_type = "?"
        details = ""
        
        if byte == 0xFF:
            i += 1
            mt = track_data[i]; i += 1
            length = 0
            b2 = track_data[i]; i += 1
            while b2 & 0x80:
                length = (length << 7) | (b2 & 0x7F)
                if i >= len(track_data): break
                b2 = track_data[i]; i += 1
            length = (length << 7) | (b2 & 0x7F)
            
            event_type = f"meta FF:{mt:02x}"
            if mt == 0x51:
                tbytes = track_data[i:i+3]
                tempo = (tbytes[0]<<16)|(tbytes[1]<<8)|tbytes[2]
                details = f"tempo={tempo} ({60000000/tempo:.1f} BPM)"
                i += 3
            elif mt == 0x3F:
                details = "End of Track"
            elif mt == 0x03 or mt == 0x04 or mt == 0x01:
                txt = track_data[i:i+length].decode('latin-1', errors='replace')[:40]
                details = f"text: {txt}"
                i += length
            else:
                details = f"len={length}"
                i += length
        
        elif byte == 0xF0 or byte == 0xF7:
            event_type = f"sysex F{byte:X}"
            i += 1
            length = 0
            b2 = track_data[i]; i += 1
            while b2 & 0x80:
                length = (length << 7) | (b2 & 0x7F)
                if i >= len(track_data): break
                b2 = track_data[i]; i += 1
            length = (length << 7) | (b2 & 0x7F)
            details = f"len={length}"
            i += length
        
        elif byte < 0x80:
            # Could be running status or data byte of previous message
            if events_count == 0:
                print(f"  [event {events_count}] delta={delta} BYTE={byte:02x} (no previous status)")
                i += 1
                events_count += 1
                continue
            
            status = running_status
            msg_type = (status >> 4) & 0x0F
            channel = status & 0x0F
            names = ['note-off','note-on','poly-aftertouch','control-change','program-change','channel-aftertouch','pitch-bend']
            event_type = f"{names[msg_type]} ch{channel+1}"
            
            if msg_type in [0,1,2,3]:
                d1 = track_data[i]; i += 1
                d2 = track_data[i]; i += 1
                if msg_type == 1 and d2 > 0:
                    notes_found.append((d1, d2))
                details = f"ch={channel+1} d1={d1} d2={d2}"
            elif msg_type == 4:
                d1 = track_data[i]; i += 1
                details = f"prog={d1} ch={channel+1}"
            elif msg_type == 6:
                d1 = track_data[i]; i += 1
                d2 = track_data[i]; i += 1
                details = f"pitch bend ch={channel+1} d1={d1} d2={d2}"
            else:
                i += 1
                details = f"unknown msg_type={msg_type}"
        
        else:
            # New status byte
            running_status = byte
            status = byte
            msg_type = (status >> 4) & 0x0F
            channel = status & 0x0F
            names = ['note-off','note-on','poly-aftertouch','control-change','program-change','channel-aftertouch','pitch-bend']
            event_type = f"{names[msg_type]} ch{channel+1}"
            
            if msg_type in [0,1,2,3]:
                d1 = track_data[i]; i += 1
                d2 = track_data[i]; i += 1
                if msg_type == 1 and d2 > 0:
                    notes_found.append((d1, d2))
                details = f"ch={channel+1} d1={d1} d2={d2}"
            elif msg_type == 4:
                d1 = track_data[i]; i += 1
                details = f"prog={d1} ch={channel+1}"
            elif msg_type == 6:
                d1 = track_data[i]; i += 1
                d2 = track_data[i]; i += 1
                details = f"pitch bend ch={channel+1} d1={d1} d2={d2}"
            else:
                i += 1
                details = f"unknown msg_type={msg_type}"
        
        if events_count < 30 or event_type.startswith(('note-on', 'meta FF:51', 'End of Track')):
            print(f"  [event {events_count}] delta={delta} {event_type:25s} {details}")
        
        events_count += 1
    
    if i >= len(track_data):
        print(f"\n  ... and {events_count - 30} more events (showing first 30)\n")
    else:
        print(f"\n  ⚠️ UNPARSED: byte={track_data[i]:02x} at offset {i}")
    
    print(f"  Total events parsed: {events_count}")
    print(f"  Notes found: {len(notes_found)}")
    if notes_found:
        for n in notes_found[:5]:
            print(f"    note-on MIDI {n[0]} vel {n[1]}")
