#!/usr/bin/env python3
"""
Patch speaker.py in-place to be headless-safe.
Replaces the sd.OutputStream block with a dummy loop that just sends READY.
"""
import os

SPEAKER_PATH = "/opt/qwen3-tts/qwen3_tts_gguf/inference/workers/speaker.py"

with open(SPEAKER_PATH, "r") as f:
    content = f.read()

# Replace the try block at the end of speaker_worker_proc
old = '''    try:
        with sd.OutputStream(samplerate=sample_rate, channels=1, callback=audio_callback, blocksize=2048):
            # 握手
            if result_queue:
                result_queue.put(SpeakerResponse(msg_type="READY"))

            while True:
                time.sleep(0.2)
                if state.get("stop"): break
    except KeyboardInterrupt:
        pass
    except Exception as e:
        print(f"❌ [SpeakerWorker] 异常: {e}")'''

new = '''    try:
        with sd.OutputStream(samplerate=sample_rate, channels=1, callback=audio_callback, blocksize=2048):
            # 握手
            if result_queue:
                result_queue.put(SpeakerResponse(msg_type="READY"))

            while True:
                time.sleep(0.2)
                if state.get("stop"): break
    except KeyboardInterrupt:
        pass
    except Exception as e:
        print(f"⚠️ [SpeakerWorker] No audio device, running headless: {e}")
        # Headless fallback: send READY and drain queue without playback
        if result_queue:
            result_queue.put(SpeakerResponse(msg_type="READY"))
        while not state.get("stop"):
            try:
                command = play_queue.get(timeout=0.5)
                handle_command(command, state)
            except Exception:
                pass'''

if old in content:
    content = content.replace(old, new)
    with open(SPEAKER_PATH, "w") as f:
        f.write(content)
    print("OK: speaker.py patched with headless fallback")
else:
    print("WARNING: exact match not found, trying simplified patch...")
    # Try to find and patch just the except Exception block
    if '❌ [SpeakerWorker] 异常' in content:
        content = content.replace(
            'print(f"❌ [SpeakerWorker] 异常: {e}")',
            '''print(f"⚠️ [SpeakerWorker] No audio device, running headless: {e}")
        # Headless fallback: send READY and drain queue without playback
        if result_queue:
            result_queue.put(SpeakerResponse(msg_type="READY"))
        while not state.get("stop"):
            try:
                command = play_queue.get(timeout=0.5)
                handle_command(command, state)
            except Exception:
                pass'''
        )
        with open(SPEAKER_PATH, "w") as f:
            f.write(content)
        print("OK: speaker.py patched (simplified)")
    else:
        print("ERROR: Could not find patch target in speaker.py")
