#!/usr/bin/env python3
"""Test different PCM streaming approaches on G1 voice service."""

import sys
import time
import json
import wave
import numpy as np
from pathlib import Path
from unitree_sdk2py.core.channel import ChannelFactoryInitialize
from unitree_sdk2py.g1.audio.g1_audio_client import AudioClient
from unitree_sdk2py.g1.audio.g1_audio_api import *

if len(sys.argv) < 2:
    print(f"Usage: python3 {sys.argv[0]} <network_interface>")
    sys.exit(1)

ChannelFactoryInitialize(0, sys.argv[1])
client = AudioClient()
client.SetTimeout(10.0)
client.Init()

# Load a small WAV chunk
wav_path = Path(__file__).parent / "DataG1" / "greeting.wav"
with wave.open(str(wav_path), "rb") as wf:
    pcm_all = wf.readframes(wf.getnframes())
    rate = wf.getframerate()
    channels = wf.getnchannels()

print(f"Loaded {len(pcm_all)} bytes, {rate}Hz, {channels}ch")
chunk = pcm_all[:2048]  # small test chunk

print("\n=== Approach 1: Register stream then send binary chunks ===")
# Step 1: Open stream
param = json.dumps({"app_name": "rec", "stream_id": "s1"})
code, data = client._Call(ROBOT_API_ID_AUDIO_START_PLAY, param)
print(f"  Open stream: code={code}, data={data}")

# Step 2: Send binary chunk (no reply)
try:
    client._CallBinaryNoReply(ROBOT_API_ID_AUDIO_START_PLAY, list(chunk))
    print("  _CallBinaryNoReply: sent (no reply)")
except Exception as e:
    print(f"  _CallBinaryNoReply: {e}")

time.sleep(1)

# Step 3: Stop
param_stop = json.dumps({"app_name": "rec"})
code, _ = client._Call(ROBOT_API_ID_AUDIO_STOP_PLAY, param_stop)
print(f"  Stop: code={code}")

print("\n=== Approach 2: _CallNoReply with JSON+PCM ===")
try:
    param2 = json.dumps({"app_name": "rec2", "stream_id": "s2", "pcm": list(chunk[:512])})
    client._CallNoReply(ROBOT_API_ID_AUDIO_START_PLAY, param2)
    print("  _CallNoReply: sent")
except Exception as e:
    print(f"  _CallNoReply: {e}")

time.sleep(1)

print("\n=== Approach 3: Multiple small _CallBinary chunks ===")
# Register first
param3 = json.dumps({"app_name": "rec3", "stream_id": "s3"})
code, _ = client._Call(ROBOT_API_ID_AUDIO_START_PLAY, param3)
print(f"  Register: code={code}")

for i in range(5):
    off = i * 512
    small = pcm_all[off:off+512]
    try:
        code, _ = client._CallBinary(ROBOT_API_ID_AUDIO_START_PLAY, list(small))
        print(f"  Chunk {i}: code={code}")
    except Exception as e:
        print(f"  Chunk {i}: {e}")
        break

print("\n=== Approach 4: Check all registered API methods ===")
for api_name, api_id in [
    ("TTS", ROBOT_API_ID_AUDIO_TTS),
    ("ASR", ROBOT_API_ID_AUDIO_ASR),
    ("START_PLAY", ROBOT_API_ID_AUDIO_START_PLAY),
    ("STOP_PLAY", ROBOT_API_ID_AUDIO_STOP_PLAY),
    ("GET_VOLUME", ROBOT_API_ID_AUDIO_GET_VOLUME),
    ("SET_VOLUME", ROBOT_API_ID_AUDIO_SET_VOLUME),
    ("SET_RGB_LED", ROBOT_API_ID_AUDIO_SET_RGB_LED),
]:
    print(f"  {api_name} = {api_id}")

print("\n=== Approach 5: TTS with file path (maybe voice service can play files?) ===")
# Try passing a file path to TTS or a special API
param5 = json.dumps({"file": "/tmp/greeting.wav"})
code, data = client._Call(ROBOT_API_ID_AUDIO_START_PLAY, param5)
print(f"  file path via START_PLAY: code={code}, data={data}")

param5b = json.dumps({"url": "/tmp/greeting.wav"})
code, data = client._Call(ROBOT_API_ID_AUDIO_START_PLAY, param5b)
print(f"  url path via START_PLAY:  code={code}, data={data}")

param5c = json.dumps({"path": "/tmp/greeting.wav"})
code, data = client._Call(ROBOT_API_ID_AUDIO_START_PLAY, param5c)
print(f"  path via START_PLAY:      code={code}, data={data}")

print("\nDone. Did you hear anything?")
