//! Shared, UI-agnostic client plumbing, extracted verbatim from the GTK client
//! (design: punktfunk-planning `linux-client-rearchitecture.md`, Phase 0) so the desktop
//! shells and the Vulkan session binary build on one implementation — on Linux AND
//! Windows (the session binary runs on both; macOS stays `wol`-only, clients/apple is
//! the client there).
//!
//! Nothing here may depend on a UI toolkit: the presenter contract is `session`'s
//! channels (`SessionHandle`) and `video`'s `DecodedImage` (RGBA bytes, dmabuf fds +
//! plane layout, or a decoded VkImage) — how frames reach the screen is the consumer's
//! business.
//!
//! Audio is the one per-OS module swap: `audio.rs` (PipeWire) on Linux,
//! `audio_wasapi.rs` (WASAPI) on Windows — same public surface, picked here by `#[path]`
//! so `crate::audio` is the only name the session pump ever sees. `keymap` (evdev-keyed)
//! stays Linux: the session path uses pf-presenter's SDL-scancode table instead.

// Unsafe-proof program: every `unsafe {}` / `unsafe impl` in this crate carries a `// SAFETY:`
// proof of why it is sound. This crate held ~91 unsafe items with NO enforcement while every
// other subsystem crate denied it — the decoders' `unsafe impl Send`s had a one-line aside
// instead of an argument precisely because nothing required one.

#[cfg(any(target_os = "linux", windows))]
mod au_dump;
#[cfg(target_os = "linux")]
pub mod audio;
#[cfg(windows)]
#[path = "audio_wasapi.rs"]
pub mod audio;
// The playback vitals both twins publish from their device callback and the decode thread logs
// — atomics only, because the PipeWire callback runs on the graph's realtime loop.
#[cfg(any(target_os = "linux", windows))]
pub mod audio_vitals;
// Best-effort priority for the threads that FEED the device callbacks (decode leg, pad-audio
// renderer, the WASAPI loops): rtkit / the Realtime portal on Linux, MMCSS on Windows.
#[cfg(any(target_os = "linux", windows))]
pub mod audio_rt;
#[cfg(any(target_os = "linux", windows))]
pub mod discovery;
#[cfg(any(target_os = "linux", windows))]
pub mod gamepad;
// The menu-event vocabulary + synthesizer and the pad descriptors, portable: `gamepad`
// (the SDL3 service) re-exports them on the desktop; the Android client feeds the same
// synthesizer from Kotlin-captured pad samples (design/android-skia-console-port.md D4).
#[cfg(any(target_os = "linux", windows, target_os = "android"))]
pub mod menu_nav;
// The audio-format vocabulary (`session` re-exports it) and the decoder-preference
// migration (`video` re-exports it): two settings-screen inputs the console needs on
// every platform, split out so the platform-bound modules can stay platform-bound.
#[cfg(any(target_os = "linux", windows, target_os = "android"))]
pub mod audio_format;
#[cfg(any(target_os = "linux", windows, target_os = "android"))]
pub mod decoder_pref;
// The console shell's platform-facing data types (actions it raises, pointer input,
// session phases) — shared by the Vulkan session's overlay and the Android GL host.
#[cfg(any(target_os = "linux", windows, target_os = "android"))]
pub mod console;
#[cfg(target_os = "linux")]
pub mod keymap;
// The library MODEL (`GameEntry`, `Artwork`, the running set) is portable — the Skia console
// renders it on Android too; the ureq fetches inside the module stay desktop-gated.
#[cfg(any(target_os = "linux", windows, target_os = "android"))]
pub mod library;
// Per-host catalog cache, so a library screen has titles to show while a sleeping host boots.
#[cfg(any(target_os = "linux", windows))]
pub mod library_cache;
// Android-enabled for the RING half (note/render — std only): the client's "Send logs to
// host" needs the ring on every platform. The `send_to_host` uploader inside stays
// desktop-gated with the rest of the ureq fetches; Android posts the rendered bundle
// through its own mTLS OkHttp client (`SkiaConsole.sendLogs`).
#[cfg(any(target_os = "linux", windows, target_os = "android"))]
pub mod logring;
// The `punktfunk://` grammar (design/client-deep-links.md §2): one parser/emitter for the
// shells, the session and the CLI, held to the Swift/Kotlin ports by a shared vector file.
#[cfg(any(target_os = "linux", windows, target_os = "android"))]
pub mod deeplink;
// The brain layer (design/client-architecture-split.md §3): what a connect is, the wake
// state machine every front-end drives, and the session spawn + stdout contract.
#[cfg(any(target_os = "linux", windows))]
pub mod orchestrate;
// The session's effective access, client-side (design/per-client-access.md §7): the
// snapshot type over the shared grant vocabulary, the derived preset label, the overlay
// chip's text and the AccessUpdate toast wording. Pure presentation logic — the
// Apple/Android ports mirror its rules rather than link it. Gated with the session
// modules only because macOS has no punktfunk-core dependency to name the grants with.
#[cfg(any(target_os = "linux", windows))]
pub mod access;
// The host's OS-identity chain (mDNS `os=` TXT): sanitize + icon-walk order. Pure string
// logic, built everywhere (the Apple/Android ports mirror it rather than link it).
pub mod os;
// "A system overlay owns the controller" for gamescope Gaming Mode — the signal behind the
// gamepad input mask, which SDL's own focus gate structurally cannot provide there.
#[cfg(target_os = "linux")]
pub mod overlay_focus;
// Client settings profiles: the override catalog + the one connect-time resolver
// (design/client-settings-profiles.md §4). Sits beside `trust`, which owns the host records
// the bindings live on.
// Pad audio (the 0xD1 plane): DualSense voice-coil haptics + speaker rendered on the wired
// physical pad's own 4-ch audio device — correlation, the per-session renderer worker, and
// the tier-A pad registry the gamepad worker feeds it through.
#[cfg(any(target_os = "linux", windows))]
pub mod pad_audio;
#[cfg(any(target_os = "linux", windows, target_os = "android"))]
pub mod profiles;
#[cfg(any(target_os = "linux", windows))]
pub mod session;
#[cfg(any(target_os = "linux", windows, target_os = "android"))]
pub mod trust;
// "Is a newer client available, and can this box install it?" — the client half of the
// signed-manifest update check the host already runs (design: host-update-from-web-console.md).
// Linux only: the Windows client ships inside the host installer and the Mac one through
// clients/apple, so neither has a package to reason about here.
#[cfg(target_os = "linux")]
pub mod update;
#[cfg(any(target_os = "linux", windows))]
pub mod video;
#[cfg(any(target_os = "linux", windows))]
mod video_color;
#[cfg(any(target_os = "linux", windows))]
mod video_software;
// Native VAAPI decode (M6 of the native-decode program): pf-vaadec's plans driven
// straight into libva, dlopen'd at runtime, exporting DRM-PRIME dmabufs the presenter
// imports. Since M10 it is the ONLY VAAPI rung there is — the libavcodec one it
// replaced is deleted — so `auto` reaches it wherever the vendor order puts VAAPI
// first; `PUNKTFUNK_DECODER=native-vaapi` reaches it by pin regardless. See `video`'s
// evidence table for what hardware has actually run it.
#[cfg(target_os = "linux")]
pub mod video_vaapi_native;
// Native Vulkan Video decode (WP-C of the native-decode program, HEVC added by M3
// WP-2, AV1 by M7): pf-vkdecode's H.264/H.265/AV1 decoders on the presenter's shared
// device — auto's TOP rung on both desktop OSes since M9, for all three codecs (each
// leg has hardware parity against libavcodec; see `video`'s evidence table), also
// pinnable via `PUNKTFUNK_DECODER=native-vulkan`.
#[cfg(any(target_os = "linux", windows))]
mod video_vk_native;
// The OS-clipboard bridge for the shared clipboard (design/clipboard-and-file-transfer.md §5).
// Built everywhere the session client is; the platform seam inside is Windows-real,
// stub elsewhere.
#[cfg(any(target_os = "linux", windows))]
pub mod clipboard;
// PyroWave decode — Linux + Windows (plan §4.5; the Apple Metal port is its own phase).
// Windows joined once its client moved to the SAME spawned Vulkan session presenter as
// Linux's: the decoder is plain Vulkan compute on the presenter's device (no fds, no
// dmabuf, no D3D11 interop), so the old "Windows present-path decision" that gated it
// resolved itself — the present path is now literally the same code.
// D3D11 decode-device plumbing: the shareable-texture hand-off ring, the decode-device
// creation and `display_hdr_volume`. Field-proven, FFmpeg-free code that
// `video_d3d11_native` (and `clients/session`) build on; the libavcodec DECODER that used
// to live alongside it went with M10's excision.
#[cfg(windows)]
pub mod video_d3d11;
// Native D3D11VA (M5): `ID3D11VideoDecoder` driven from pf-bitstream plans, filling the
// hand-off ring `video_d3d11` owns. Since M10 it is the only DXVA rung there is. In `auto`
// for all three codecs, each of which now has hardware evidence — H.264/H.265 since M5, AV1
// since 2026-08-07 — see `video`'s evidence table; `PUNKTFUNK_DECODER=native-d3d11va`
// reaches every leg by pin.
#[cfg(windows)]
pub mod video_d3d11_native;
#[cfg(all(any(target_os = "linux", windows), feature = "pyrowave"))]
pub mod video_pyrowave;

pub mod wol;
