// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// from webkit-gir-files
// DO NOT EDIT

use crate::{
    ffi, CookieManager, Download, ITPThirdParty, MemoryPressureSettings, NetworkProxyMode,
    NetworkProxySettings, TLSErrorsPolicy, WebsiteDataManager,
};
use glib::{
    prelude::*,
    signal::{connect_raw, SignalHandlerId},
    translate::*,
};
use std::{boxed::Box as Box_, pin::Pin};

glib::wrapper! {
    #[doc(alias = "WebKitNetworkSession")]
    pub struct NetworkSession(Object<ffi::WebKitNetworkSession, ffi::WebKitNetworkSessionClass>);

    match fn {
        type_ => || ffi::webkit_network_session_get_type(),
    }
}

impl NetworkSession {
    #[doc(alias = "webkit_network_session_new")]
    pub fn new(data_directory: Option<&str>, cache_directory: Option<&str>) -> NetworkSession {
        assert_initialized_main_thread!();
        unsafe {
            from_glib_full(ffi::webkit_network_session_new(
                data_directory.to_glib_none().0,
                cache_directory.to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "webkit_network_session_new_ephemeral")]
    pub fn new_ephemeral() -> NetworkSession {
        assert_initialized_main_thread!();
        unsafe { from_glib_full(ffi::webkit_network_session_new_ephemeral()) }
    }

    // rustdoc-stripper-ignore-next
    /// Creates a new builder-pattern struct instance to construct [`NetworkSession`] objects.
    ///
    /// This method returns an instance of [`NetworkSessionBuilder`](crate::builders::NetworkSessionBuilder) which can be used to create [`NetworkSession`] objects.
    pub fn builder() -> NetworkSessionBuilder {
        NetworkSessionBuilder::new()
    }

    #[doc(alias = "webkit_network_session_allow_tls_certificate_for_host")]
    pub fn allow_tls_certificate_for_host(
        &self,
        certificate: &impl IsA<gio::TlsCertificate>,
        host: &str,
    ) {
        unsafe {
            ffi::webkit_network_session_allow_tls_certificate_for_host(
                self.to_glib_none().0,
                certificate.as_ref().to_glib_none().0,
                host.to_glib_none().0,
            );
        }
    }

    #[doc(alias = "webkit_network_session_download_uri")]
    pub fn download_uri(&self, uri: &str) -> Option<Download> {
        unsafe {
            from_glib_full(ffi::webkit_network_session_download_uri(
                self.to_glib_none().0,
                uri.to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "webkit_network_session_get_cookie_manager")]
    #[doc(alias = "get_cookie_manager")]
    pub fn cookie_manager(&self) -> Option<CookieManager> {
        unsafe {
            from_glib_none(ffi::webkit_network_session_get_cookie_manager(
                self.to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "webkit_network_session_get_itp_enabled")]
    #[doc(alias = "get_itp_enabled")]
    pub fn is_itp_enabled(&self) -> bool {
        unsafe {
            from_glib(ffi::webkit_network_session_get_itp_enabled(
                self.to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "webkit_network_session_get_itp_summary")]
    #[doc(alias = "get_itp_summary")]
    pub fn itp_summary<P: FnOnce(Result<Vec<ITPThirdParty>, glib::Error>) + 'static>(
        &self,
        cancellable: Option<&impl IsA<gio::Cancellable>>,
        callback: P,
    ) {
        let main_context = glib::MainContext::ref_thread_default();
        let is_main_context_owner = main_context.is_owner();
        let has_acquired_main_context = (!is_main_context_owner)
            .then(|| main_context.acquire().ok())
            .flatten();
        assert!(
            is_main_context_owner || has_acquired_main_context.is_some(),
            "Async operations only allowed if the thread is owning the MainContext"
        );

        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
        unsafe extern "C" fn itp_summary_trampoline<
            P: FnOnce(Result<Vec<ITPThirdParty>, glib::Error>) + 'static,
        >(
            _source_object: *mut glib::gobject_ffi::GObject,
            res: *mut gio::ffi::GAsyncResult,
            user_data: glib::ffi::gpointer,
        ) {
            let mut error = std::ptr::null_mut();
            let ret = ffi::webkit_network_session_get_itp_summary_finish(
                _source_object as *mut _,
                res,
                &mut error,
            );
            let result = if error.is_null() {
                Ok(FromGlibPtrContainer::from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            };
            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
                Box_::from_raw(user_data as *mut _);
            let callback: P = callback.into_inner();
            callback(result);
        }
        let callback = itp_summary_trampoline::<P>;
        unsafe {
            ffi::webkit_network_session_get_itp_summary(
                self.to_glib_none().0,
                cancellable.map(|p| p.as_ref()).to_glib_none().0,
                Some(callback),
                Box_::into_raw(user_data) as *mut _,
            );
        }
    }

    pub fn itp_summary_future(
        &self,
    ) -> Pin<
        Box_<dyn std::future::Future<Output = Result<Vec<ITPThirdParty>, glib::Error>> + 'static>,
    > {
        Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
            obj.itp_summary(Some(cancellable), move |res| {
                send.resolve(res);
            });
        }))
    }

    #[doc(alias = "webkit_network_session_get_persistent_credential_storage_enabled")]
    #[doc(alias = "get_persistent_credential_storage_enabled")]
    pub fn is_persistent_credential_storage_enabled(&self) -> bool {
        unsafe {
            from_glib(
                ffi::webkit_network_session_get_persistent_credential_storage_enabled(
                    self.to_glib_none().0,
                ),
            )
        }
    }

    #[doc(alias = "webkit_network_session_get_tls_errors_policy")]
    #[doc(alias = "get_tls_errors_policy")]
    pub fn tls_errors_policy(&self) -> TLSErrorsPolicy {
        unsafe {
            from_glib(ffi::webkit_network_session_get_tls_errors_policy(
                self.to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "webkit_network_session_get_website_data_manager")]
    #[doc(alias = "get_website_data_manager")]
    pub fn website_data_manager(&self) -> Option<WebsiteDataManager> {
        unsafe {
            from_glib_none(ffi::webkit_network_session_get_website_data_manager(
                self.to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "webkit_network_session_is_ephemeral")]
    pub fn is_ephemeral(&self) -> bool {
        unsafe {
            from_glib(ffi::webkit_network_session_is_ephemeral(
                self.to_glib_none().0,
            ))
        }
    }

    #[doc(alias = "webkit_network_session_prefetch_dns")]
    pub fn prefetch_dns(&self, hostname: &str) {
        unsafe {
            ffi::webkit_network_session_prefetch_dns(
                self.to_glib_none().0,
                hostname.to_glib_none().0,
            );
        }
    }

    #[doc(alias = "webkit_network_session_set_itp_enabled")]
    pub fn set_itp_enabled(&self, enabled: bool) {
        unsafe {
            ffi::webkit_network_session_set_itp_enabled(self.to_glib_none().0, enabled.into_glib());
        }
    }

    #[doc(alias = "webkit_network_session_set_persistent_credential_storage_enabled")]
    pub fn set_persistent_credential_storage_enabled(&self, enabled: bool) {
        unsafe {
            ffi::webkit_network_session_set_persistent_credential_storage_enabled(
                self.to_glib_none().0,
                enabled.into_glib(),
            );
        }
    }

    #[doc(alias = "webkit_network_session_set_proxy_settings")]
    pub fn set_proxy_settings(
        &self,
        proxy_mode: NetworkProxyMode,
        proxy_settings: Option<&NetworkProxySettings>,
    ) {
        unsafe {
            ffi::webkit_network_session_set_proxy_settings(
                self.to_glib_none().0,
                proxy_mode.into_glib(),
                mut_override(proxy_settings.to_glib_none().0),
            );
        }
    }

    #[doc(alias = "webkit_network_session_set_tls_errors_policy")]
    pub fn set_tls_errors_policy(&self, policy: TLSErrorsPolicy) {
        unsafe {
            ffi::webkit_network_session_set_tls_errors_policy(
                self.to_glib_none().0,
                policy.into_glib(),
            );
        }
    }

    #[doc(alias = "webkit_network_session_get_default")]
    #[doc(alias = "get_default")]
    #[allow(clippy::should_implement_trait)]
    pub fn default() -> Option<NetworkSession> {
        assert_initialized_main_thread!();
        unsafe { from_glib_none(ffi::webkit_network_session_get_default()) }
    }

    #[doc(alias = "webkit_network_session_set_memory_pressure_settings")]
    pub fn set_memory_pressure_settings(settings: &mut MemoryPressureSettings) {
        assert_initialized_main_thread!();
        unsafe {
            ffi::webkit_network_session_set_memory_pressure_settings(settings.to_glib_none_mut().0);
        }
    }

    #[doc(alias = "download-started")]
    pub fn connect_download_started<F: Fn(&Self, &Download) + 'static>(
        &self,
        f: F,
    ) -> SignalHandlerId {
        unsafe extern "C" fn download_started_trampoline<
            F: Fn(&NetworkSession, &Download) + 'static,
        >(
            this: *mut ffi::WebKitNetworkSession,
            download: *mut ffi::WebKitDownload,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(&from_glib_borrow(this), &from_glib_borrow(download))
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                b"download-started\0".as_ptr() as *const _,
                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
                    download_started_trampoline::<F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }
}

impl Default for NetworkSession {
    fn default() -> Self {
        glib::object::Object::new::<Self>()
    }
}

// rustdoc-stripper-ignore-next
/// A [builder-pattern] type to construct [`NetworkSession`] objects.
///
/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html
#[must_use = "The builder must be built to be used"]
pub struct NetworkSessionBuilder {
    builder: glib::object::ObjectBuilder<'static, NetworkSession>,
}

impl NetworkSessionBuilder {
    fn new() -> Self {
        Self {
            builder: glib::object::Object::builder(),
        }
    }

    pub fn cache_directory(self, cache_directory: impl Into<glib::GString>) -> Self {
        Self {
            builder: self
                .builder
                .property("cache-directory", cache_directory.into()),
        }
    }

    pub fn data_directory(self, data_directory: impl Into<glib::GString>) -> Self {
        Self {
            builder: self
                .builder
                .property("data-directory", data_directory.into()),
        }
    }

    pub fn is_ephemeral(self, is_ephemeral: bool) -> Self {
        Self {
            builder: self.builder.property("is-ephemeral", is_ephemeral),
        }
    }

    // rustdoc-stripper-ignore-next
    /// Build the [`NetworkSession`].
    #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"]
    pub fn build(self) -> NetworkSession {
        self.builder.build()
    }
}
