#![forbid(unsafe_code)]

use gstreamer as gst;

/// Pick the client-side H.264 decoder in a predictable preference order.
///
/// Inputs: none, though operators may override the choice with
/// `LESAVKA_H264_DECODER=<element>`.
/// Outputs: the chosen decoder element name, or `decodebin` as a last-resort
/// fallback when no explicit decoder is present.
/// Why: `decodebin` is flexible, but a stable preference order makes decode
/// behavior easier to reason about and compare in diagnostics.
#[must_use]
pub fn pick_h264_decoder() -> String {
    if let Ok(raw) = std::env::var("LESAVKA_H264_DECODER") {
        let name = raw.trim();
        if name.eq_ignore_ascii_case("decodebin") {
            return "decodebin".to_string();
        }
        if !name.is_empty() && buildable_decoder(name) {
            return name.to_string();
        }
    }

    for name in [
        "avdec_h264",
        "openh264dec",
        "nvh264dec",
        "nvh264sldec",
        "vah264dec",
        "vaapih264dec",
        "v4l2h264dec",
        "v4l2slh264dec",
    ] {
        if buildable_decoder(name) {
            return name.to_string();
        }
    }

    "decodebin".to_string()
}

fn buildable_decoder(name: &str) -> bool {
    #[cfg(coverage)]
    if std::env::var("TEST_FAIL_GST_INIT").is_ok() {
        return false;
    }
    if gst::init().is_err() {
        return false;
    }
    #[cfg(coverage)]
    if std::env::var("TEST_DISABLE_H264_DECODER_FACTORY").is_ok() {
        return false;
    }
    gst::ElementFactory::find(name).is_some() && gst::ElementFactory::make(name).build().is_ok()
}
