// spell-checker:disable

/// Return the platform `strerror(errno)` message as an owned `String`.
/// Returns `None` when the runtime gives no description for `errno`.
#[cfg(any(unix, windows))]
#[must_use]
pub fn strerror_string(errno: i32) -> Option<String> {
    let ptr = unsafe { libc::strerror(errno) };
    if ptr.is_null() {
        return None;
    }
    let s = unsafe { core::ffi::CStr::from_ptr(ptr) }.to_string_lossy();
    Some(s.into_owned())
}

#[cfg(any(unix, windows, target_os = "wasi"))]
pub mod errors {
    pub use libc::*;
    #[cfg(windows)]
    pub use windows_sys::Win32::{
        Foundation::*,
        Networking::WinSock::{
            WSABASEERR, WSADESCRIPTION_LEN, WSAEACCES, WSAEADDRINUSE, WSAEADDRNOTAVAIL,
            WSAEAFNOSUPPORT, WSAEALREADY, WSAEBADF, WSAECANCELLED, WSAECONNABORTED,
            WSAECONNREFUSED, WSAECONNRESET, WSAEDESTADDRREQ, WSAEDISCON, WSAEDQUOT, WSAEFAULT,
            WSAEHOSTDOWN, WSAEHOSTUNREACH, WSAEINPROGRESS, WSAEINTR, WSAEINVAL,
            WSAEINVALIDPROCTABLE, WSAEINVALIDPROVIDER, WSAEISCONN, WSAELOOP, WSAEMFILE,
            WSAEMSGSIZE, WSAENAMETOOLONG, WSAENETDOWN, WSAENETRESET, WSAENETUNREACH, WSAENOBUFS,
            WSAENOMORE, WSAENOPROTOOPT, WSAENOTCONN, WSAENOTEMPTY, WSAENOTSOCK, WSAEOPNOTSUPP,
            WSAEPFNOSUPPORT, WSAEPROCLIM, WSAEPROTONOSUPPORT, WSAEPROTOTYPE,
            WSAEPROVIDERFAILEDINIT, WSAEREFUSED, WSAEREMOTE, WSAESHUTDOWN, WSAESOCKTNOSUPPORT,
            WSAESTALE, WSAETIMEDOUT, WSAETOOMANYREFS, WSAEUSERS, WSAEWOULDBLOCK, WSAID_ACCEPTEX,
            WSAID_CONNECTEX, WSAID_DISCONNECTEX, WSAID_GETACCEPTEXSOCKADDRS, WSAID_TRANSMITFILE,
            WSAID_TRANSMITPACKETS, WSAID_WSAPOLL, WSAID_WSARECVMSG, WSANO_DATA, WSANO_RECOVERY,
            WSANOTINITIALISED, WSAPROTOCOL_LEN, WSASERVICE_NOT_FOUND, WSASYS_STATUS_LEN,
            WSASYSCALLFAILURE, WSASYSNOTREADY, WSATRY_AGAIN, WSATYPE_NOT_FOUND, WSAVERNOTSUPPORTED,
        },
    };
    #[cfg(windows)]
    macro_rules! reexport_wsa {
        ($($errname:ident),*$(,)?) => {
            paste::paste! {
                $(pub const $errname: i32 = windows_sys::Win32::Networking::WinSock:: [<WSA $errname>] as i32;)*
            }
        }
    }
    #[cfg(windows)]
    reexport_wsa! {
        EADDRINUSE, EADDRNOTAVAIL, EAFNOSUPPORT, EALREADY, ECONNABORTED, ECONNREFUSED, ECONNRESET,
        EDESTADDRREQ, EDQUOT, EHOSTDOWN, EHOSTUNREACH, EINPROGRESS, EISCONN, ELOOP, EMSGSIZE,
        ENETDOWN, ENETRESET, ENETUNREACH, ENOBUFS, ENOPROTOOPT, ENOTCONN, ENOTSOCK, EOPNOTSUPP,
        EPFNOSUPPORT, EPROTONOSUPPORT, EPROTOTYPE, EREMOTE, ESHUTDOWN, ESOCKTNOSUPPORT, ESTALE,
        ETIMEDOUT, ETOOMANYREFS, EUSERS, EWOULDBLOCK,
        // TODO: EBADF should be here once winerrs are translated to errnos but it messes up some things atm
    }
}
