    {- |
    Copyright  : Will Thompson, Iñaki García Etxebarria and Jonas Platte
    License    : LGPL-2.1
    Maintainer : Iñaki García Etxebarria (garetxe@gmail.com)

    This 'GI.Gio.Objects.SocketControlMessage.SocketControlMessage' contains a 'GI.Gio.Objects.UnixFDList.UnixFDList'.
    It may be sent using 'GI.Gio.Objects.Socket.socketSendMessage' and received using
    'GI.Gio.Objects.Socket.socketReceiveMessage' over UNIX sockets (ie: sockets in the
    @/G_SOCKET_ADDRESS_UNIX/@ family). The file descriptors are copied
    between processes by the kernel.

    For an easier way to send and receive file descriptors over
    stream-oriented UNIX sockets, see 'GI.Gio.Objects.UnixConnection.unixConnectionSendFd' and
    'GI.Gio.Objects.UnixConnection.unixConnectionReceiveFd'.

    Note that @\<gio\/gunixfdmessage.h>@ belongs to the UNIX-specific GIO
    interfaces, thus you have to use the @gio-unix-2.0.pc@ pkg-config
    file when using it.
    -}

    #define ENABLE_OVERLOADING \
           (!defined(__HADDOCK_VERSION__))

    module GI.Gio.Objects.UnixFDMessage
        (

    -- * Exported types
        UnixFDMessage(..)                       ,
        IsUnixFDMessage                         ,
        toUnixFDMessage                         ,
        noUnixFDMessage                         ,

     -- * Methods
    -- ** appendFd #method:appendFd#

    #if ENABLE_OVERLOADING
        UnixFDMessageAppendFdMethodInfo         ,
    #endif
        unixFDMessageAppendFd                   ,

    -- ** getFdList #method:getFdList#

    #if ENABLE_OVERLOADING
        UnixFDMessageGetFdListMethodInfo        ,
    #endif
        unixFDMessageGetFdList                  ,

    -- ** new #method:new#

        unixFDMessageNew                        ,

    -- ** newWithFdList #method:newWithFdList#

        unixFDMessageNewWithFdList              ,

    -- ** stealFds #method:stealFds#

    #if ENABLE_OVERLOADING
        UnixFDMessageStealFdsMethodInfo         ,
    #endif
        unixFDMessageStealFds                   ,

     -- * Properties
    -- ** fdList #attr:fdList#
    {- | /No description available in the introspection data./
    -}
    #if ENABLE_OVERLOADING
        UnixFDMessageFdListPropertyInfo         ,
    #endif
        constructUnixFDMessageFdList            ,
        getUnixFDMessageFdList                  ,
    #if ENABLE_OVERLOADING
        unixFDMessageFdList                     ,
    #endif

        ) where

    import Data.GI.Base.ShortPrelude
    import qualified Data.GI.Base.ShortPrelude as SP
    import qualified Data.GI.Base.Overloading as O
    import qualified Prelude as P

    import qualified Data.GI.Base.Attributes as GI.Attributes
    import qualified Data.GI.Base.ManagedPtr as B.ManagedPtr
    import qualified Data.GI.Base.GError as B.GError
    import qualified Data.GI.Base.GVariant as B.GVariant
    import qualified Data.GI.Base.GValue as B.GValue
    import qualified Data.GI.Base.GParamSpec as B.GParamSpec
    import qualified Data.GI.Base.CallStack as B.CallStack
    import qualified Data.Text as T
    import qualified Data.ByteString.Char8 as B
    import qualified Data.Map as Map
    import qualified Foreign.Ptr as FP

    import qualified GI.GObject.Objects.Object as GObject.Object
    import {-# SOURCE #-} qualified GI.Gio.Objects.SocketControlMessage as Gio.SocketControlMessage
    import {-# SOURCE #-} qualified GI.Gio.Objects.UnixFDList as Gio.UnixFDList

    -- | Memory-managed wrapper type.
    newtype UnixFDMessage = UnixFDMessage (ManagedPtr UnixFDMessage)
    foreign import ccall "g_unix_fd_message_get_type"
        c_g_unix_fd_message_get_type :: IO GType

    instance GObject UnixFDMessage where
        gobjectType _ = c_g_unix_fd_message_get_type

    -- | Type class for types which can be safely cast to `UnixFDMessage`, for instance with `toUnixFDMessage`.
    class GObject o => IsUnixFDMessage o
    #if MIN_VERSION_base(4,9,0)
    instance {-# OVERLAPPABLE #-} (GObject a, O.UnknownAncestorError UnixFDMessage a) =>
        IsUnixFDMessage a
    #endif
    instance IsUnixFDMessage UnixFDMessage
    instance Gio.SocketControlMessage.IsSocketControlMessage UnixFDMessage
    instance GObject.Object.IsObject UnixFDMessage

    -- | Cast to `UnixFDMessage`, for types for which this is known to be safe. For general casts, use `Data.GI.Base.ManagedPtr.castTo`.
    toUnixFDMessage :: (MonadIO m, IsUnixFDMessage o) => o -> m UnixFDMessage
    toUnixFDMessage = liftIO . unsafeCastTo UnixFDMessage

    -- | A convenience alias for `Nothing` :: `Maybe` `UnixFDMessage`.
    noUnixFDMessage :: Maybe UnixFDMessage
    noUnixFDMessage = Nothing

    #if ENABLE_OVERLOADING
    type family ResolveUnixFDMessageMethod (t :: Symbol) (o :: *) :: * where
        ResolveUnixFDMessageMethod "appendFd" o = UnixFDMessageAppendFdMethodInfo
        ResolveUnixFDMessageMethod "bindProperty" o = GObject.Object.ObjectBindPropertyMethodInfo
        ResolveUnixFDMessageMethod "bindPropertyFull" o = GObject.Object.ObjectBindPropertyFullMethodInfo
        ResolveUnixFDMessageMethod "forceFloating" o = GObject.Object.ObjectForceFloatingMethodInfo
        ResolveUnixFDMessageMethod "freezeNotify" o = GObject.Object.ObjectFreezeNotifyMethodInfo
        ResolveUnixFDMessageMethod "getv" o = GObject.Object.ObjectGetvMethodInfo
        ResolveUnixFDMessageMethod "isFloating" o = GObject.Object.ObjectIsFloatingMethodInfo
        ResolveUnixFDMessageMethod "notify" o = GObject.Object.ObjectNotifyMethodInfo
        ResolveUnixFDMessageMethod "notifyByPspec" o = GObject.Object.ObjectNotifyByPspecMethodInfo
        ResolveUnixFDMessageMethod "ref" o = GObject.Object.ObjectRefMethodInfo
        ResolveUnixFDMessageMethod "refSink" o = GObject.Object.ObjectRefSinkMethodInfo
        ResolveUnixFDMessageMethod "runDispose" o = GObject.Object.ObjectRunDisposeMethodInfo
        ResolveUnixFDMessageMethod "serialize" o = Gio.SocketControlMessage.SocketControlMessageSerializeMethodInfo
        ResolveUnixFDMessageMethod "stealData" o = GObject.Object.ObjectStealDataMethodInfo
        ResolveUnixFDMessageMethod "stealFds" o = UnixFDMessageStealFdsMethodInfo
        ResolveUnixFDMessageMethod "stealQdata" o = GObject.Object.ObjectStealQdataMethodInfo
        ResolveUnixFDMessageMethod "thawNotify" o = GObject.Object.ObjectThawNotifyMethodInfo
        ResolveUnixFDMessageMethod "unref" o = GObject.Object.ObjectUnrefMethodInfo
        ResolveUnixFDMessageMethod "watchClosure" o = GObject.Object.ObjectWatchClosureMethodInfo
        ResolveUnixFDMessageMethod "getData" o = GObject.Object.ObjectGetDataMethodInfo
        ResolveUnixFDMessageMethod "getFdList" o = UnixFDMessageGetFdListMethodInfo
        ResolveUnixFDMessageMethod "getLevel" o = Gio.SocketControlMessage.SocketControlMessageGetLevelMethodInfo
        ResolveUnixFDMessageMethod "getMsgType" o = Gio.SocketControlMessage.SocketControlMessageGetMsgTypeMethodInfo
        ResolveUnixFDMessageMethod "getProperty" o = GObject.Object.ObjectGetPropertyMethodInfo
        ResolveUnixFDMessageMethod "getQdata" o = GObject.Object.ObjectGetQdataMethodInfo
        ResolveUnixFDMessageMethod "getSize" o = Gio.SocketControlMessage.SocketControlMessageGetSizeMethodInfo
        ResolveUnixFDMessageMethod "setData" o = GObject.Object.ObjectSetDataMethodInfo
        ResolveUnixFDMessageMethod "setProperty" o = GObject.Object.ObjectSetPropertyMethodInfo
        ResolveUnixFDMessageMethod l o = O.MethodResolutionFailed l o

    instance (info ~ ResolveUnixFDMessageMethod t UnixFDMessage, O.MethodInfo info UnixFDMessage p) => O.IsLabelProxy t (UnixFDMessage -> p) where
        fromLabelProxy _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)

    #if MIN_VERSION_base(4,9,0)
    instance (info ~ ResolveUnixFDMessageMethod t UnixFDMessage, O.MethodInfo info UnixFDMessage p) => O.IsLabel t (UnixFDMessage -> p) where
    #if MIN_VERSION_base(4,10,0)
        fromLabel = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)
    #else
        fromLabel _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)
    #endif
    #endif

    #endif

    -- VVV Prop "fd-list"
       -- Type: TInterface (Name {namespace = "Gio", name = "UnixFDList"})
       -- Flags: [PropertyReadable,PropertyWritable,PropertyConstructOnly]
       -- Nullable: (Just False,Nothing)

    {- |
    Get the value of the “@fd-list@” property.
    When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

    @
    'Data.GI.Base.Attributes.get' unixFDMessage #fdList
    @
    -}
    getUnixFDMessageFdList :: (MonadIO m, IsUnixFDMessage o) => o -> m Gio.UnixFDList.UnixFDList
    getUnixFDMessageFdList obj = liftIO $ checkUnexpectedNothing "getUnixFDMessageFdList" $ getObjectPropertyObject obj "fd-list" Gio.UnixFDList.UnixFDList

    {- |
    Construct a `GValueConstruct` with valid value for the “@fd-list@” property. This is rarely needed directly, but it is used by `Data.GI.Base.Constructible.new`.
    -}
    constructUnixFDMessageFdList :: (IsUnixFDMessage o, Gio.UnixFDList.IsUnixFDList a) => a -> IO (GValueConstruct o)
    constructUnixFDMessageFdList val = constructObjectPropertyObject "fd-list" (Just val)

    #if ENABLE_OVERLOADING
    data UnixFDMessageFdListPropertyInfo
    instance AttrInfo UnixFDMessageFdListPropertyInfo where
        type AttrAllowedOps UnixFDMessageFdListPropertyInfo = '[ 'AttrConstruct, 'AttrGet, 'AttrClear]
        type AttrSetTypeConstraint UnixFDMessageFdListPropertyInfo = Gio.UnixFDList.IsUnixFDList
        type AttrBaseTypeConstraint UnixFDMessageFdListPropertyInfo = IsUnixFDMessage
        type AttrGetType UnixFDMessageFdListPropertyInfo = Gio.UnixFDList.UnixFDList
        type AttrLabel UnixFDMessageFdListPropertyInfo = "fd-list"
        type AttrOrigin UnixFDMessageFdListPropertyInfo = UnixFDMessage
        attrGet _ = getUnixFDMessageFdList
        attrSet _ = undefined
        attrConstruct _ = constructUnixFDMessageFdList
        attrClear _ = undefined
    #endif

    #if ENABLE_OVERLOADING
    instance O.HasAttributeList UnixFDMessage
    type instance O.AttributeList UnixFDMessage = UnixFDMessageAttributeList
    type UnixFDMessageAttributeList = ('[ '("fdList", UnixFDMessageFdListPropertyInfo)] :: [(Symbol, *)])
    #endif

    #if ENABLE_OVERLOADING
    unixFDMessageFdList :: AttrLabelProxy "fdList"
    unixFDMessageFdList = AttrLabelProxy

    #endif

    #if ENABLE_OVERLOADING
    type instance O.SignalList UnixFDMessage = UnixFDMessageSignalList
    type UnixFDMessageSignalList = ('[ '("notify", GObject.Object.ObjectNotifySignalInfo)] :: [(Symbol, *)])

    #endif

    -- method UnixFDMessage::new
    -- method type : Constructor
    -- Args : []
    -- Lengths : []
    -- returnType : Just (TInterface (Name {namespace = "Gio", name = "UnixFDMessage"}))
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_unix_fd_message_new" g_unix_fd_message_new ::
        IO (Ptr UnixFDMessage)

    {- |
    Creates a new 'GI.Gio.Objects.UnixFDMessage.UnixFDMessage' containing an empty file descriptor
    list.

    /Since: 2.22/
    -}
    unixFDMessageNew ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        m UnixFDMessage
        {- ^ __Returns:__ a new 'GI.Gio.Objects.UnixFDMessage.UnixFDMessage' -}
    unixFDMessageNew  = liftIO $ do
        result <- g_unix_fd_message_new
        checkUnexpectedReturnNULL "unixFDMessageNew" result
        result' <- (wrapObject UnixFDMessage) result
        return result'

    #if ENABLE_OVERLOADING
    #endif

    -- method UnixFDMessage::new_with_fd_list
    -- method type : Constructor
    -- Args : [Arg {argCName = "fd_list", argType = TInterface (Name {namespace = "Gio", name = "UnixFDList"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GUnixFDList", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Just (TInterface (Name {namespace = "Gio", name = "UnixFDMessage"}))
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_unix_fd_message_new_with_fd_list" g_unix_fd_message_new_with_fd_list ::
        Ptr Gio.UnixFDList.UnixFDList ->        -- fd_list : TInterface (Name {namespace = "Gio", name = "UnixFDList"})
        IO (Ptr UnixFDMessage)

    {- |
    Creates a new 'GI.Gio.Objects.UnixFDMessage.UnixFDMessage' containing /@list@/.

    /Since: 2.24/
    -}
    unixFDMessageNewWithFdList ::
        (B.CallStack.HasCallStack, MonadIO m, Gio.UnixFDList.IsUnixFDList a) =>
        a
        {- ^ /@fdList@/: a 'GI.Gio.Objects.UnixFDList.UnixFDList' -}
        -> m UnixFDMessage
        {- ^ __Returns:__ a new 'GI.Gio.Objects.UnixFDMessage.UnixFDMessage' -}
    unixFDMessageNewWithFdList fdList = liftIO $ do
        fdList' <- unsafeManagedPtrCastPtr fdList
        result <- g_unix_fd_message_new_with_fd_list fdList'
        checkUnexpectedReturnNULL "unixFDMessageNewWithFdList" result
        result' <- (wrapObject UnixFDMessage) result
        touchManagedPtr fdList
        return result'

    #if ENABLE_OVERLOADING
    #endif

    -- method UnixFDMessage::append_fd
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "message", argType = TInterface (Name {namespace = "Gio", name = "UnixFDMessage"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GUnixFDMessage", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "fd", argType = TBasicType TInt, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a valid open file descriptor", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Just (TBasicType TBoolean)
    -- throws : True
    -- Skip return : False

    foreign import ccall "g_unix_fd_message_append_fd" g_unix_fd_message_append_fd ::
        Ptr UnixFDMessage ->                    -- message : TInterface (Name {namespace = "Gio", name = "UnixFDMessage"})
        Int32 ->                                -- fd : TBasicType TInt
        Ptr (Ptr GError) ->                     -- error
        IO CInt

    {- |
    Adds a file descriptor to /@message@/.

    The file descriptor is duplicated using @/dup()/@. You keep your copy
    of the descriptor and the copy contained in /@message@/ will be closed
    when /@message@/ is finalized.

    A possible cause of failure is exceeding the per-process or
    system-wide file descriptor limit.

    /Since: 2.22/
    -}
    unixFDMessageAppendFd ::
        (B.CallStack.HasCallStack, MonadIO m, IsUnixFDMessage a) =>
        a
        {- ^ /@message@/: a 'GI.Gio.Objects.UnixFDMessage.UnixFDMessage' -}
        -> Int32
        {- ^ /@fd@/: a valid open file descriptor -}
        -> m ()
        {- ^ /(Can throw 'Data.GI.Base.GError.GError')/ -}
    unixFDMessageAppendFd message fd = liftIO $ do
        message' <- unsafeManagedPtrCastPtr message
        onException (do
            _ <- propagateGError $ g_unix_fd_message_append_fd message' fd
            touchManagedPtr message
            return ()
         ) (do
            return ()
         )

    #if ENABLE_OVERLOADING
    data UnixFDMessageAppendFdMethodInfo
    instance (signature ~ (Int32 -> m ()), MonadIO m, IsUnixFDMessage a) => O.MethodInfo UnixFDMessageAppendFdMethodInfo a signature where
        overloadedMethod _ = unixFDMessageAppendFd

    #endif

    -- method UnixFDMessage::get_fd_list
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "message", argType = TInterface (Name {namespace = "Gio", name = "UnixFDMessage"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GUnixFDMessage", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Just (TInterface (Name {namespace = "Gio", name = "UnixFDList"}))
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_unix_fd_message_get_fd_list" g_unix_fd_message_get_fd_list ::
        Ptr UnixFDMessage ->                    -- message : TInterface (Name {namespace = "Gio", name = "UnixFDMessage"})
        IO (Ptr Gio.UnixFDList.UnixFDList)

    {- |
    Gets the 'GI.Gio.Objects.UnixFDList.UnixFDList' contained in /@message@/.  This function does not
    return a reference to the caller, but the returned list is valid for
    the lifetime of /@message@/.

    /Since: 2.24/
    -}
    unixFDMessageGetFdList ::
        (B.CallStack.HasCallStack, MonadIO m, IsUnixFDMessage a) =>
        a
        {- ^ /@message@/: a 'GI.Gio.Objects.UnixFDMessage.UnixFDMessage' -}
        -> m Gio.UnixFDList.UnixFDList
        {- ^ __Returns:__ the 'GI.Gio.Objects.UnixFDList.UnixFDList' from /@message@/ -}
    unixFDMessageGetFdList message = liftIO $ do
        message' <- unsafeManagedPtrCastPtr message
        result <- g_unix_fd_message_get_fd_list message'
        checkUnexpectedReturnNULL "unixFDMessageGetFdList" result
        result' <- (newObject Gio.UnixFDList.UnixFDList) result
        touchManagedPtr message
        return result'

    #if ENABLE_OVERLOADING
    data UnixFDMessageGetFdListMethodInfo
    instance (signature ~ (m Gio.UnixFDList.UnixFDList), MonadIO m, IsUnixFDMessage a) => O.MethodInfo UnixFDMessageGetFdListMethodInfo a signature where
        overloadedMethod _ = unixFDMessageGetFdList

    #endif

    -- method UnixFDMessage::steal_fds
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "message", argType = TInterface (Name {namespace = "Gio", name = "UnixFDMessage"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GUnixFDMessage", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "length", argType = TBasicType TInt, direction = DirectionOut, mayBeNull = False, argDoc = Documentation {rawDocText = Just "pointer to the length of the returned\n    array, or %NULL", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferEverything}]
    -- Lengths : [Arg {argCName = "length", argType = TBasicType TInt, direction = DirectionOut, mayBeNull = False, argDoc = Documentation {rawDocText = Just "pointer to the length of the returned\n    array, or %NULL", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferEverything}]
    -- returnType : Just (TCArray False (-1) 1 (TBasicType TInt))
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_unix_fd_message_steal_fds" g_unix_fd_message_steal_fds ::
        Ptr UnixFDMessage ->                    -- message : TInterface (Name {namespace = "Gio", name = "UnixFDMessage"})
        Ptr Int32 ->                            -- length : TBasicType TInt
        IO (Ptr Int32)

    {- |
    Returns the array of file descriptors that is contained in this
    object.

    After this call, the descriptors are no longer contained in
    /@message@/. Further calls will return an empty list (unless more
    descriptors have been added).

    The return result of this function must be freed with 'GI.GLib.Functions.free'.
    The caller is also responsible for closing all of the file
    descriptors.

    If /@length@/ is non-'Nothing' then it is set to the number of file
    descriptors in the returned array. The returned array is also
    terminated with -1.

    This function never returns 'Nothing'. In case there are no file
    descriptors contained in /@message@/, an empty array is returned.

    /Since: 2.22/
    -}
    unixFDMessageStealFds ::
        (B.CallStack.HasCallStack, MonadIO m, IsUnixFDMessage a) =>
        a
        {- ^ /@message@/: a 'GI.Gio.Objects.UnixFDMessage.UnixFDMessage' -}
        -> m [Int32]
        {- ^ __Returns:__ an array of file
        descriptors -}
    unixFDMessageStealFds message = liftIO $ do
        message' <- unsafeManagedPtrCastPtr message
        length_ <- allocMem :: IO (Ptr Int32)
        result <- g_unix_fd_message_steal_fds message' length_
        length_' <- peek length_
        checkUnexpectedReturnNULL "unixFDMessageStealFds" result
        result' <- (unpackStorableArrayWithLength length_') result
        freeMem result
        touchManagedPtr message
        freeMem length_
        return result'

    #if ENABLE_OVERLOADING
    data UnixFDMessageStealFdsMethodInfo
    instance (signature ~ (m [Int32]), MonadIO m, IsUnixFDMessage a) => O.MethodInfo UnixFDMessageStealFdsMethodInfo a signature where
        overloadedMethod _ = unixFDMessageStealFds

    #endif