/* el_peripheral_null.c — the no-device build of El's I/O organ.
 *
 * Every entry point declared in el_runtime.h's "Peripheral" block, implemented
 * as an honest refusal. This is what a platform without an El audio/capture
 * realizer links instead of el_audio_darwin.m + el_capture_darwin.m, so an El
 * program that speaks or listens still COMPILES AND LINKS everywhere.
 *
 * The distinction that matters: these do not pretend. speaker_available() and
 * mic_available() return 0, and every operation returns its failure sentinel.
 * A program asking "can I speak here?" gets a truthful no, rather than a
 * silence it would have to infer something from. Silent success is the failure
 * mode this whole change exists to eliminate — El spent this entire codebase's
 * history writing WAV files full of zeros and reporting ok=true, and nobody
 * caught it because nothing ever said "there is no sound here".
 *
 * Compiled INSTEAD OF the Darwin realizers, never alongside them — the symbols
 * are the same by design, which is the point: the El side never branches on
 * platform, it branches on speaker_available().
 */

#include "el_runtime.h"

#if !defined(__APPLE__)

/* ── Speaker ─────────────────────────────────────────────────────────────── */

el_val_t speaker_available(void) { return (el_val_t)0; }
el_val_t speaker_name(void)      { return EL_STR("none"); }

el_val_t speaker_play_pcm16(el_val_t samples, el_val_t sample_rate) {
    (void)samples; (void)sample_rate;
    return (el_val_t)0;
}

el_val_t speaker_play_wav(el_val_t path) {
    (void)path;
    return (el_val_t)0;
}

el_val_t speaker_play_pcm16_async(el_val_t samples, el_val_t sample_rate) {
    (void)samples; (void)sample_rate;
    return (el_val_t)0;
}

el_val_t speaker_play_wav_async(el_val_t path) {
    (void)path;
    return (el_val_t)0;
}

el_val_t speaker_pause(void)          { return (el_val_t)0; }
el_val_t speaker_resume(void)         { return (el_val_t)0; }
el_val_t speaker_playing(void)        { return (el_val_t)0; }
el_val_t speaker_stop(void)           { return (el_val_t)0; }
el_val_t speaker_played_frames(void)  { return (el_val_t)0; }

/* WAV geometry is pure parsing and would work fine here, but reporting a
 * duration for audio this build cannot play would invite a caller to sequence
 * around a silence. Refuse consistently with the rest of the file. */
el_val_t wav_frames(el_val_t path) { (void)path; return (el_val_t)0; }
el_val_t wav_rate(el_val_t path)   { (void)path; return (el_val_t)0; }

/* ── Microphone ──────────────────────────────────────────────────────────── */

el_val_t mic_available(void)       { return (el_val_t)0; }
el_val_t mic_request_access(void)  { return (el_val_t)0; }

/* Empty list, not 0: the contract says capture returns samples, and a caller
 * iterating the result must find nothing rather than dereference a non-list. */
el_val_t mic_capture_pcm16(el_val_t seconds, el_val_t sample_rate) {
    (void)seconds; (void)sample_rate;
    return el_list_empty();
}

el_val_t mic_monitor_start(void) { return (el_val_t)0; }
el_val_t mic_monitor_rms(void)   { return el_from_float(0.0); }
el_val_t mic_monitor_stop(void)  { return (el_val_t)0; }

/* ── Camera ──────────────────────────────────────────────────────────────── */

el_val_t camera_available(void)      { return (el_val_t)0; }
el_val_t camera_request_access(void) { return (el_val_t)0; }
el_val_t camera_capture_rgb(void)    { return (el_val_t)0; }

el_val_t camera_capture_jpeg(el_val_t path) {
    (void)path;
    return (el_val_t)0;
}

#endif /* !__APPLE__ */
