// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
// DO NOT EDIT

use crate::{Bin, ClockTime, DebugGraphDetails, DebugLevel, Element, StackTraceFlags, ffi};
use glib::{prelude::*, translate::*};
#[cfg(feature = "v1_28")]
#[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
use std::boxed::Box as Box_;

#[cfg(feature = "v1_28")]
#[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
#[doc(alias = "gst_call_async")]
pub fn call_async<P: FnOnce() + Send + Sync + 'static>(func: P) {
    assert_initialized_main_thread!();
    let func_data: Box_<P> = Box_::new(func);
    unsafe extern "C" fn func_func<P: FnOnce() + Send + Sync + 'static>(
        user_data: glib::ffi::gpointer,
    ) {
        unsafe {
            let callback = Box_::from_raw(user_data as *mut P);
            (*callback)()
        }
    }
    let func = Some(func_func::<P> as _);
    let super_callback0: Box_<P> = func_data;
    unsafe {
        ffi::gst_call_async(func, Box_::into_raw(super_callback0) as *mut _);
    }
}

#[cfg(feature = "v1_28")]
#[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
#[doc(alias = "gst_check_version")]
pub fn check_version(major: u32, minor: u32, micro: u32) -> bool {
    assert_initialized_main_thread!();
    unsafe { from_glib(ffi::gst_check_version(major, minor, micro)) }
}

#[cfg(feature = "v1_28")]
#[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
#[doc(alias = "gst_cpuid_supports_arm_neon")]
pub fn cpuid_supports_arm_neon() -> bool {
    assert_initialized_main_thread!();
    unsafe { from_glib(ffi::gst_cpuid_supports_arm_neon()) }
}

#[cfg(feature = "v1_28")]
#[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
#[doc(alias = "gst_cpuid_supports_arm_neon64")]
pub fn cpuid_supports_arm_neon64() -> bool {
    assert_initialized_main_thread!();
    unsafe { from_glib(ffi::gst_cpuid_supports_arm_neon64()) }
}

#[cfg(feature = "v1_28")]
#[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
#[doc(alias = "gst_cpuid_supports_x86_3dnow")]
pub fn cpuid_supports_x86_3dnow() -> bool {
    assert_initialized_main_thread!();
    unsafe { from_glib(ffi::gst_cpuid_supports_x86_3dnow()) }
}

#[cfg(feature = "v1_28")]
#[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
#[doc(alias = "gst_cpuid_supports_x86_avx")]
pub fn cpuid_supports_x86_avx() -> bool {
    assert_initialized_main_thread!();
    unsafe { from_glib(ffi::gst_cpuid_supports_x86_avx()) }
}

#[cfg(feature = "v1_28")]
#[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
#[doc(alias = "gst_cpuid_supports_x86_avx2")]
pub fn cpuid_supports_x86_avx2() -> bool {
    assert_initialized_main_thread!();
    unsafe { from_glib(ffi::gst_cpuid_supports_x86_avx2()) }
}

#[cfg(feature = "v1_28")]
#[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
#[doc(alias = "gst_cpuid_supports_x86_mmx")]
pub fn cpuid_supports_x86_mmx() -> bool {
    assert_initialized_main_thread!();
    unsafe { from_glib(ffi::gst_cpuid_supports_x86_mmx()) }
}

#[cfg(feature = "v1_28")]
#[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
#[doc(alias = "gst_cpuid_supports_x86_mmxext")]
pub fn cpuid_supports_x86_mmxext() -> bool {
    assert_initialized_main_thread!();
    unsafe { from_glib(ffi::gst_cpuid_supports_x86_mmxext()) }
}

#[cfg(feature = "v1_28")]
#[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
#[doc(alias = "gst_cpuid_supports_x86_sse2")]
pub fn cpuid_supports_x86_sse2() -> bool {
    assert_initialized_main_thread!();
    unsafe { from_glib(ffi::gst_cpuid_supports_x86_sse2()) }
}

#[cfg(feature = "v1_28")]
#[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
#[doc(alias = "gst_cpuid_supports_x86_sse3")]
pub fn cpuid_supports_x86_sse3() -> bool {
    assert_initialized_main_thread!();
    unsafe { from_glib(ffi::gst_cpuid_supports_x86_sse3()) }
}

#[cfg(feature = "v1_28")]
#[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
#[doc(alias = "gst_cpuid_supports_x86_sse4_1")]
pub fn cpuid_supports_x86_sse4_1() -> bool {
    assert_initialized_main_thread!();
    unsafe { from_glib(ffi::gst_cpuid_supports_x86_sse4_1()) }
}

#[cfg(feature = "v1_28")]
#[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
#[doc(alias = "gst_cpuid_supports_x86_sse4_2")]
pub fn cpuid_supports_x86_sse4_2() -> bool {
    assert_initialized_main_thread!();
    unsafe { from_glib(ffi::gst_cpuid_supports_x86_sse4_2()) }
}

#[cfg(feature = "v1_28")]
#[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
#[doc(alias = "gst_cpuid_supports_x86_ssse3")]
pub fn cpuid_supports_x86_ssse3() -> bool {
    assert_initialized_main_thread!();
    unsafe { from_glib(ffi::gst_cpuid_supports_x86_ssse3()) }
}

#[doc(alias = "gst_debug_add_ring_buffer_logger")]
pub fn debug_add_ring_buffer_logger(max_size_per_thread: u32, thread_timeout: u32) {
    skip_assert_initialized!();
    unsafe {
        ffi::gst_debug_add_ring_buffer_logger(max_size_per_thread, thread_timeout);
    }
}

#[doc(alias = "gst_debug_bin_to_dot_data")]
pub fn debug_bin_to_dot_data(bin: &impl IsA<Bin>, details: DebugGraphDetails) -> glib::GString {
    skip_assert_initialized!();
    unsafe {
        from_glib_full(ffi::gst_debug_bin_to_dot_data(
            bin.as_ref().to_glib_none().0,
            details.into_glib(),
        ))
    }
}

#[doc(alias = "gst_debug_bin_to_dot_file")]
pub fn debug_bin_to_dot_file(
    bin: &impl IsA<Bin>,
    details: DebugGraphDetails,
    file_name: Option<impl AsRef<std::path::Path>>,
) {
    skip_assert_initialized!();
    unsafe {
        ffi::gst_debug_bin_to_dot_file(
            bin.as_ref().to_glib_none().0,
            details.into_glib(),
            file_name.as_ref().map(|p| p.as_ref()).to_glib_none().0,
        );
    }
}

#[doc(alias = "gst_debug_bin_to_dot_file_with_ts")]
pub fn debug_bin_to_dot_file_with_ts(
    bin: &impl IsA<Bin>,
    details: DebugGraphDetails,
    file_name: Option<impl AsRef<std::path::Path>>,
) {
    skip_assert_initialized!();
    unsafe {
        ffi::gst_debug_bin_to_dot_file_with_ts(
            bin.as_ref().to_glib_none().0,
            details.into_glib(),
            file_name.as_ref().map(|p| p.as_ref()).to_glib_none().0,
        );
    }
}

#[doc(alias = "gst_debug_get_default_threshold")]
pub fn debug_get_default_threshold() -> DebugLevel {
    skip_assert_initialized!();
    unsafe { from_glib(ffi::gst_debug_get_default_threshold()) }
}

#[doc(alias = "gst_debug_get_stack_trace")]
pub fn debug_get_stack_trace(flags: StackTraceFlags) -> Result<glib::GString, glib::BoolError> {
    skip_assert_initialized!();
    unsafe {
        Option::<_>::from_glib_full(ffi::gst_debug_get_stack_trace(flags.into_glib()))
            .ok_or_else(|| glib::bool_error!("Failed to get stack trace"))
    }
}

#[doc(alias = "gst_debug_is_active")]
pub fn debug_is_active() -> bool {
    skip_assert_initialized!();
    unsafe { from_glib(ffi::gst_debug_is_active()) }
}

#[doc(alias = "gst_debug_is_colored")]
pub fn debug_is_colored() -> bool {
    skip_assert_initialized!();
    unsafe { from_glib(ffi::gst_debug_is_colored()) }
}

#[doc(alias = "gst_debug_print_stack_trace")]
pub fn debug_print_stack_trace() {
    skip_assert_initialized!();
    unsafe {
        ffi::gst_debug_print_stack_trace();
    }
}

#[doc(alias = "gst_debug_remove_ring_buffer_logger")]
pub fn debug_remove_ring_buffer_logger() {
    skip_assert_initialized!();
    unsafe {
        ffi::gst_debug_remove_ring_buffer_logger();
    }
}

#[doc(alias = "gst_debug_ring_buffer_logger_get_logs")]
pub fn debug_ring_buffer_logger_get_logs() -> Vec<glib::GString> {
    skip_assert_initialized!();
    unsafe { FromGlibPtrContainer::from_glib_full(ffi::gst_debug_ring_buffer_logger_get_logs()) }
}

#[doc(alias = "gst_debug_set_active")]
pub fn debug_set_active(active: bool) {
    skip_assert_initialized!();
    unsafe {
        ffi::gst_debug_set_active(active.into_glib());
    }
}

#[doc(alias = "gst_debug_set_colored")]
pub fn debug_set_colored(colored: bool) {
    skip_assert_initialized!();
    unsafe {
        ffi::gst_debug_set_colored(colored.into_glib());
    }
}

#[doc(alias = "gst_debug_set_default_threshold")]
pub fn debug_set_default_threshold(level: DebugLevel) {
    skip_assert_initialized!();
    unsafe {
        ffi::gst_debug_set_default_threshold(level.into_glib());
    }
}

#[doc(alias = "gst_debug_set_threshold_for_name")]
pub fn debug_set_threshold_for_name(name: &str, level: DebugLevel) {
    skip_assert_initialized!();
    unsafe {
        ffi::gst_debug_set_threshold_for_name(name.to_glib_none().0, level.into_glib());
    }
}

#[doc(alias = "gst_debug_set_threshold_from_string")]
pub fn debug_set_threshold_from_string(list: &str, reset: bool) {
    skip_assert_initialized!();
    unsafe {
        ffi::gst_debug_set_threshold_from_string(list.to_glib_none().0, reset.into_glib());
    }
}

#[doc(alias = "gst_debug_unset_threshold_for_name")]
pub fn debug_unset_threshold_for_name(name: &str) {
    skip_assert_initialized!();
    unsafe {
        ffi::gst_debug_unset_threshold_for_name(name.to_glib_none().0);
    }
}

#[doc(alias = "gst_get_main_executable_path")]
#[doc(alias = "get_main_executable_path")]
pub fn main_executable_path() -> Result<glib::GString, glib::BoolError> {
    assert_initialized_main_thread!();
    unsafe {
        Option::<_>::from_glib_none(ffi::gst_get_main_executable_path())
            .ok_or_else(|| glib::bool_error!("Failed to get main executable path"))
    }
}

#[doc(alias = "gst_parse_bin_from_description")]
pub fn parse_bin_from_description(
    bin_description: &str,
    ghost_unlinked_pads: bool,
) -> Result<Bin, glib::Error> {
    assert_initialized_main_thread!();
    unsafe {
        let mut error = std::ptr::null_mut();
        let ret = ffi::gst_parse_bin_from_description(
            bin_description.to_glib_none().0,
            ghost_unlinked_pads.into_glib(),
            &mut error,
        );
        if error.is_null() {
            Ok(from_glib_none(ret))
        } else {
            Err(from_glib_full(error))
        }
    }
}

#[doc(alias = "gst_parse_launch")]
pub fn parse_launch(pipeline_description: &str) -> Result<Element, glib::Error> {
    assert_initialized_main_thread!();
    unsafe {
        let mut error = std::ptr::null_mut();
        let ret = ffi::gst_parse_launch(pipeline_description.to_glib_none().0, &mut error);
        if error.is_null() {
            Ok(from_glib_none(ret))
        } else {
            Err(from_glib_full(error))
        }
    }
}

#[doc(alias = "gst_parse_launchv")]
pub fn parse_launchv(argv: &[&str]) -> Result<Element, glib::Error> {
    assert_initialized_main_thread!();
    unsafe {
        let mut error = std::ptr::null_mut();
        let ret = ffi::gst_parse_launchv(argv.to_glib_none().0, &mut error);
        if error.is_null() {
            Ok(from_glib_none(ret))
        } else {
            Err(from_glib_full(error))
        }
    }
}

#[doc(alias = "gst_update_registry")]
pub fn update_registry() -> Result<(), glib::error::BoolError> {
    assert_initialized_main_thread!();
    unsafe {
        glib::result_from_gboolean!(ffi::gst_update_registry(), "Failed to update the registry")
    }
}

#[doc(alias = "gst_util_get_timestamp")]
pub fn util_get_timestamp() -> ClockTime {
    skip_assert_initialized!();
    unsafe { try_from_glib(ffi::gst_util_get_timestamp()).expect("mandatory glib value is None") }
}

#[doc(alias = "gst_version")]
pub fn version() -> (u32, u32, u32, u32) {
    skip_assert_initialized!();
    unsafe {
        let mut major = std::mem::MaybeUninit::uninit();
        let mut minor = std::mem::MaybeUninit::uninit();
        let mut micro = std::mem::MaybeUninit::uninit();
        let mut nano = std::mem::MaybeUninit::uninit();
        ffi::gst_version(
            major.as_mut_ptr(),
            minor.as_mut_ptr(),
            micro.as_mut_ptr(),
            nano.as_mut_ptr(),
        );
        (
            major.assume_init(),
            minor.assume_init(),
            micro.assume_init(),
            nano.assume_init(),
        )
    }
}

#[doc(alias = "gst_version_string")]
pub fn version_string() -> glib::GString {
    skip_assert_initialized!();
    unsafe { from_glib_full(ffi::gst_version_string()) }
}
