#ifndef BEATRAT_AUDIO_DEVICE_H
#define BEATRAT_AUDIO_DEVICE_H

#include <alsa/asoundlib.h>
#include <pthread.h>

/* Opens a PCM for the given stream direction (SND_PCM_STREAM_PLAYBACK or
 * SND_PCM_STREAM_CAPTURE), preferring a self-contained in-memory PipeWire
 * device definition and falling back to "default" if that's unavailable
 * (e.g. no PipeWire installed at all -- plain ALSA hardware/dmix still
 * works). label is just for log messages ("playback"/"capture"). */
snd_pcm_t *audio_open_pcm(snd_pcm_stream_t stream, const char *label);

/* Configures format/rate/channels on an already-open PCM. latency_us is
 * the requested overall buffer latency in microseconds. */
int audio_configure_pcm(snd_pcm_t *pcm, unsigned rate, unsigned channels,
                         snd_pcm_format_t format, unsigned latency_us,
                         const char *label);

/* Attempts to raise the calling thread to SCHED_FIFO at the given
 * priority. Logs a warning and returns -1 on failure (e.g. insufficient
 * permissions) rather than treating it as fatal -- caller should just
 * continue at normal priority either way. */
int audio_try_realtime_priority(int priority, const char *label);

#define AUDIO_MAX_DEVICES 16

typedef struct {
    char name[128]; /* ALSA device name to pass to snd_pcm_open, e.g. "hw:0,0" */
    char desc[256]; /* human-readable description for the UI */
} AudioDeviceInfo;

/* Enumerates real ALSA PCM devices (via snd_device_name_hint) for the
 * given direction. Returns the number of devices written into out (up
 * to max_count). This is a real hardware list -- it does NOT include
 * our own PipeWire-preferring "auto" behavior, which the UI should
 * represent as a separate, always-present option rather than an entry
 * here. */
int audio_enumerate_devices(AudioDeviceInfo *out, int max_count, int want_output);

/* Opens a specific named device directly (no PipeWire-preference
 * logic) -- for when the user has explicitly chosen a device rather
 * than asking for the automatic behavior. */
snd_pcm_t *audio_open_pcm_named(snd_pcm_stream_t stream, const char *device_name, const char *label);

/* Opens AND configures a named device, retrying through ALSA's "plug"
 * conversion layer if the device rejects our format directly. Some
 * named PCM types (surroundXX, iec958, etc.) hard-declare a fixed
 * channel count and refuse anything else outright with no
 * auto-conversion -- "plug:<name>" lets ALSA insert its own converter
 * in front instead of failing. Returns NULL (with both attempts
 * logged) if neither works. */
snd_pcm_t *audio_open_and_configure_named(snd_pcm_stream_t stream, const char *device_name,
                                           unsigned rate, unsigned channels, snd_pcm_format_t format,
                                           unsigned latency_us, const char *label);

#endif
