from typing import List
from pydantic import BaseModel

# Define some base to hold the relevant parameters
class AuracastQoSConfig(BaseModel):
    iso_int_multiple_10ms: int
    number_of_retransmissions: int
    max_transport_latency_ms: int

class AuracastQosHigh(AuracastQoSConfig):
    iso_int_multiple_10ms: int = 1
    number_of_retransmissions:int = 4 #4
    max_transport_latency_ms:int = 43 #varies from the default value in bumble (was 65)

class AuracastQosMid(AuracastQoSConfig):
    iso_int_multiple_10ms: int = 2
    number_of_retransmissions:int = 3
    max_transport_latency_ms:int = 65

class AuracastQosLow(AuracastQoSConfig):
    iso_int_multiple_10ms: int = 3
    number_of_retransmissions:int = 2 #4
    max_transport_latency_ms:int = 65 #varies from the default value in bumble (was 65)


class AuracastGlobalConfig(BaseModel):
    qos_config: AuracastQoSConfig =  AuracastQosHigh()
    debug: bool = False
    device_name: str = 'Auracaster'
    transport: str = ''
    auracast_device_address: str = 'F0:F1:F2:F3:F4:F5'
    auracast_sampling_rate_hz: int = 16000
    octets_per_frame: int = 40 #48kbps@24kHz # bitrate = octets_per_frame * 8 / frame len
    frame_duration_us: int = 10000
    presentation_delay_us: int = 40000
    # TODO:pydantic does not support bytes serialization - use .hex and np.fromhex()
    manufacturer_data: tuple[int, bytes] | tuple[None, None] = (None, None)

# "Audio input. "
# "'device' -> use the host's default sound input device, "
# "'device:<DEVICE_ID>' -> use one of the host's sound input devices "
# "(specify 'device:?' to get a list of available sound input devices), "
# "'stdin' -> receive audio from stdin as int16 PCM, "
# "'file:<filename> -> read audio from a .wav or raw int16 PCM file. "
class AuracastBigConfig(BaseModel):
    id: int = 123456
    random_address: str = 'F1:F1:F2:F3:F4:F5'
    code: str | None = None # Broadcast_Code – a 16-octet parameter provided by the Host
    language: str = 'eng' # See: https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes
    name: str = 'Broadcast0'
    program_info: str = 'Some Announcements'
    audio_source: str = 'file:./auracast/announcement_48_10_96000_en.wav'
    input_format: str = 'auto'
    loop: bool = True
    precode_wav: bool = False
    iso_que_len: int = 64

class AuracastBigConfigDeu(AuracastBigConfig):
    id: int = 12
    random_address: str = 'F1:F1:F2:F3:F4:F5'
    name: str = 'Broadcast0'
    language: str ='deu'
    program_info: str = 'Announcements German'
    audio_source: str = 'file:./testdata/announcement_de.wav'

class AuracastBigConfigEng(AuracastBigConfig):
    id: int = 123
    random_address: str = 'F2:F1:F2:F3:F4:F5'
    name: str  = 'Broadcast1'
    language: str ='eng'
    program_info: str  = 'Announcements English'
    audio_source: str  = 'file:./testdata/announcement_en.wav'

class AuracastBigConfigFra(AuracastBigConfig):
    id: int = 1234
    random_address: str = 'F3:F1:F2:F3:F4:F5'
    name: str  = 'Broadcast2'
    language: str ='fra'
    program_info: str  = 'Announcements French'
    audio_source: str  = 'file:./testdata/announcement_fr.wav'

class AuracastBigConfigSpa(AuracastBigConfig):
    id: int =12345
    random_address: str = 'F4:F1:F2:F3:F4:F5'
    name: str  = 'Broadcast3'
    language: str ='spa'
    program_info: str  = 'Announcements Spanish'
    audio_source: str  = 'file:./testdata/announcement_es.wav'

class AuracastBigConfigIta(AuracastBigConfig):
    id: int =1234567
    random_address: str = 'F5:F1:F2:F3:F4:F5'
    name: str  = 'Broadcast4'
    language: str ='ita'
    program_info: str  = 'Announcements Italian'
    audio_source: str  = 'file:./testdata/announcement_it.wav'


class AuracastConfigGroup(AuracastGlobalConfig):
    bigs: List[AuracastBigConfig] = [
        AuracastBigConfigDeu(),
    ]
