{-# LINE 1 "Z/IO/UV/FFI.hsc" #-}
{-# LANGUAGE CPP                        #-}
{-# LANGUAGE DeriveGeneric              #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MagicHash                  #-}
{-# LANGUAGE TypeFamilies               #-}
{-# LANGUAGE PatternSynonyms            #-}
{-# LANGUAGE UnliftedFFITypes           #-}

{-|
Module      : Z.IO.UV
Description : libuv operations
Copyright   : (c) Winterland, 2017-2018
License     : BSD
Maintainer  : drkoster@qq.com
Stability   : experimental
Portability : non-portable

INTERNAL MODULE, provides all libuv side operations.

-}

module Z.IO.UV.FFI where

import           Data.Bits
import           Data.Int
import           Data.Typeable
import           Data.Word
import           Foreign.C.String
import           Foreign.C.Types
import           Foreign.Ptr
import           Foreign.Storable
import           Z.Foreign
import           Z.IO.Network.SocketAddr    (SocketAddr)
import           System.Posix.Types (CSsize (..))
import           GHC.Generics



{-# LINE 39 "Z/IO/UV/FFI.hsc" #-}


{-# LINE 41 "Z/IO/UV/FFI.hsc" #-}

--------------------------------------------------------------------------------
-- libuv version
foreign import ccall unsafe uv_version :: IO CUInt
foreign import ccall unsafe uv_version_string :: IO CString

--------------------------------------------------------------------------------
-- Type alias
type UVSlot = Int
-- | UVSlotUnSafe wrap a slot which may not have a 'MVar' in blocking table, 
--   i.e. the blocking table need to be resized.
newtype UVSlotUnSafe = UVSlotUnSafe { unsafeGetSlot :: UVSlot }
type UVFD = Int32

--------------------------------------------------------------------------------
-- CONSTANT

pattern SO_REUSEPORT_LOAD_BALANCE :: Int
pattern SO_REUSEPORT_LOAD_BALANCE = 1
{-# LINE 60 "Z/IO/UV/FFI.hsc" #-}
pattern INIT_LOOP_SIZE :: Int
pattern INIT_LOOP_SIZE = 128
{-# LINE 62 "Z/IO/UV/FFI.hsc" #-}

--------------------------------------------------------------------------------
-- loop
data UVLoop
data UVLoopData

peekUVEventQueue :: Ptr UVLoopData -> IO (Int, Ptr Int)
peekUVEventQueue p = (,)
    <$> ((\hsc_ptr -> peekByteOff hsc_ptr 0) p)
{-# LINE 71 "Z/IO/UV/FFI.hsc" #-}
    <*> ((\hsc_ptr -> peekByteOff hsc_ptr 8) p)
{-# LINE 72 "Z/IO/UV/FFI.hsc" #-}

clearUVEventCounter :: Ptr UVLoopData -> IO ()
clearUVEventCounter p = do
    (\hsc_ptr -> pokeByteOff hsc_ptr 0) p $ (0 :: Int)
{-# LINE 76 "Z/IO/UV/FFI.hsc" #-}

peekUVBufferTable :: Ptr UVLoopData -> IO (Ptr (Ptr Word8), Ptr CSsize)
peekUVBufferTable p = (,)
    <$> ((\hsc_ptr -> peekByteOff hsc_ptr 16) p)
{-# LINE 80 "Z/IO/UV/FFI.hsc" #-}
    <*> ((\hsc_ptr -> peekByteOff hsc_ptr 24) p)
{-# LINE 81 "Z/IO/UV/FFI.hsc" #-}

newtype UVRunMode = UVRunMode CInt deriving (Eq, Ord, Typeable)

pattern UV_RUN_DEFAULT :: UVRunMode
pattern UV_RUN_DEFAULT = UVRunMode 0
{-# LINE 86 "Z/IO/UV/FFI.hsc" #-}
pattern UV_RUN_ONCE :: UVRunMode
pattern UV_RUN_ONCE    = UVRunMode 1
{-# LINE 88 "Z/IO/UV/FFI.hsc" #-}
pattern UV_RUN_NOWAIT :: UVRunMode
pattern UV_RUN_NOWAIT  = UVRunMode 2
{-# LINE 90 "Z/IO/UV/FFI.hsc" #-}

-- | Peek loop data pointer from uv loop  pointer.
peekUVLoopData :: Ptr UVLoop -> IO (Ptr UVLoopData)
peekUVLoopData p = (\hsc_ptr -> peekByteOff hsc_ptr 0) p
{-# LINE 94 "Z/IO/UV/FFI.hsc" #-}

foreign import ccall unsafe hs_uv_loop_init      :: Int -> IO (Ptr UVLoop)
foreign import ccall unsafe hs_uv_loop_close     :: Ptr UVLoop -> IO ()

-- | uv_run with usafe FFI.
foreign import ccall unsafe "hs_uv_run" uv_run    :: Ptr UVLoop -> UVRunMode -> IO CInt

-- | uv_run with safe FFI.
foreign import ccall safe "hs_uv_run" uv_run_safe :: Ptr UVLoop -> UVRunMode -> IO CInt

foreign import ccall unsafe uv_loop_alive :: Ptr UVLoop -> IO CInt

--------------------------------------------------------------------------------
-- thread safe wake up

foreign import ccall unsafe hs_uv_wake_up_timer :: Ptr UVLoopData -> IO CInt
foreign import ccall unsafe hs_uv_wake_up_async :: Ptr UVLoopData -> IO CInt

--------------------------------------------------------------------------------
-- handle
data UVHandle

peekUVHandleData :: Ptr UVHandle -> IO UVSlotUnSafe
peekUVHandleData p =  UVSlotUnSafe <$> ((\hsc_ptr -> peekByteOff hsc_ptr 0) p :: IO Int)
{-# LINE 118 "Z/IO/UV/FFI.hsc" #-}

foreign import ccall unsafe hs_uv_fileno :: Ptr UVHandle -> IO UVFD
foreign import ccall unsafe hs_uv_handle_alloc :: Ptr UVLoop -> IO (Ptr UVHandle)
foreign import ccall unsafe hs_uv_handle_free  :: Ptr UVHandle -> IO ()
foreign import ccall unsafe hs_uv_handle_close :: Ptr UVHandle -> IO ()

--------------------------------------------------------------------------------
-- request

foreign import ccall unsafe hs_uv_cancel :: Ptr UVLoop -> UVSlot -> IO ()

--------------------------------------------------------------------------------
-- stream

foreign import ccall unsafe hs_uv_listen  :: Ptr UVHandle -> CInt -> IO CInt
foreign import ccall unsafe hs_uv_listen_resume :: Ptr UVHandle -> IO ()

foreign import ccall unsafe hs_uv_read_start :: Ptr UVHandle -> IO CInt
foreign import ccall unsafe uv_read_stop :: Ptr UVHandle -> IO CInt
foreign import ccall unsafe hs_uv_write :: Ptr UVHandle -> Ptr Word8 -> Int -> IO UVSlotUnSafe

foreign import ccall unsafe hs_uv_accept_check_alloc :: Ptr UVHandle -> IO (Ptr UVHandle)
foreign import ccall unsafe hs_uv_accept_check_init :: Ptr UVHandle -> IO CInt
foreign import ccall unsafe hs_uv_accept_check_close :: Ptr UVHandle -> IO ()

--------------------------------------------------------------------------------
-- tcp & pipe
foreign import ccall unsafe hs_uv_tcp_open :: Ptr UVHandle -> UVFD -> IO CInt
foreign import ccall unsafe uv_tcp_init :: Ptr UVLoop -> Ptr UVHandle -> IO CInt
foreign import ccall unsafe uv_tcp_init_ex :: Ptr UVLoop -> Ptr UVHandle -> CUInt -> IO CInt
foreign import ccall unsafe uv_tcp_nodelay :: Ptr UVHandle -> CInt -> IO CInt
foreign import ccall unsafe uv_tcp_keepalive :: Ptr UVHandle -> CInt -> CUInt -> IO CInt
foreign import ccall unsafe uv_tcp_getsockname :: Ptr UVHandle -> MBA# SocketAddr -> MBA# CInt -> IO CInt
foreign import ccall unsafe uv_tcp_getpeername :: Ptr UVHandle -> MBA# SocketAddr -> MBA# CInt -> IO CInt

uV_TCP_IPV6ONLY :: CUInt
uV_TCP_IPV6ONLY = 1
{-# LINE 155 "Z/IO/UV/FFI.hsc" #-}

foreign import ccall unsafe uv_tcp_bind :: Ptr UVHandle -> MBA# SocketAddr -> CUInt -> IO CInt
foreign import ccall unsafe hs_uv_tcp_connect :: Ptr UVHandle -> MBA# SocketAddr -> IO UVSlotUnSafe
foreign import ccall unsafe hs_set_socket_reuse :: Ptr UVHandle -> IO CInt

foreign import ccall unsafe hs_uv_pipe_open :: Ptr UVHandle -> UVFD -> IO CInt
foreign import ccall unsafe uv_pipe_init :: Ptr UVLoop -> Ptr UVHandle -> CInt -> IO CInt
foreign import ccall unsafe uv_pipe_bind :: Ptr UVHandle -> CString -> IO CInt
foreign import ccall unsafe hs_uv_pipe_connect :: Ptr UVHandle -> CString -> IO UVSlotUnSafe

--------------------------------------------------------------------------------
-- udp
foreign import ccall unsafe uv_udp_init :: Ptr UVLoop -> Ptr UVHandle -> IO CInt
foreign import ccall unsafe uv_udp_init_ex :: Ptr UVLoop -> Ptr UVHandle -> CUInt -> IO CInt
foreign import ccall unsafe uv_udp_open :: Ptr UVHandle -> UVFD -> IO CInt
foreign import ccall unsafe uv_udp_bind :: Ptr UVHandle -> MBA# SocketAddr -> UVUDPFlag -> IO CInt

newtype UVMembership = UVMembership CInt deriving (Show, Eq, Ord)

pattern UV_LEAVE_GROUP :: UVMembership
pattern UV_LEAVE_GROUP = UVMembership 0
{-# LINE 176 "Z/IO/UV/FFI.hsc" #-}
pattern UV_JOIN_GROUP :: UVMembership
pattern UV_JOIN_GROUP = UVMembership 1
{-# LINE 178 "Z/IO/UV/FFI.hsc" #-}

newtype UVUDPFlag = UVUDPFlag CInt deriving (Show, Eq, Ord, Storable, Bits, FiniteBits, Num)

pattern UV_UDP_DEFAULT :: UVUDPFlag
pattern UV_UDP_DEFAULT = UVUDPFlag 0
pattern UV_UDP_IPV6ONLY :: UVUDPFlag
pattern UV_UDP_IPV6ONLY = UVUDPFlag 1
{-# LINE 185 "Z/IO/UV/FFI.hsc" #-}
pattern UV_UDP_REUSEADDR :: UVUDPFlag
pattern UV_UDP_REUSEADDR = UVUDPFlag 4
{-# LINE 187 "Z/IO/UV/FFI.hsc" #-}

pattern UV_UDP_PARTIAL :: Int32
pattern UV_UDP_PARTIAL = 2
{-# LINE 190 "Z/IO/UV/FFI.hsc" #-}

foreign import ccall unsafe uv_udp_connect
    :: Ptr UVHandle -> MBA# SocketAddr -> IO CInt
-- | Just pass null pointer as SocketAddr to disconnect
foreign import ccall unsafe "uv_udp_connect" uv_udp_disconnect
    :: Ptr UVHandle -> Ptr SocketAddr -> IO CInt

foreign import ccall unsafe uv_udp_set_membership ::
    Ptr UVHandle -> CString -> CString -> UVMembership -> IO CInt
foreign import ccall unsafe uv_udp_set_source_membership ::
    Ptr UVHandle -> CString -> CString -> CString -> UVMembership -> IO CInt

foreign import ccall unsafe uv_udp_set_multicast_loop :: Ptr UVHandle -> CInt -> IO CInt
foreign import ccall unsafe uv_udp_set_multicast_ttl :: Ptr UVHandle -> CInt -> IO CInt
foreign import ccall unsafe uv_udp_set_multicast_interface :: Ptr UVHandle -> CString -> IO CInt
foreign import ccall unsafe uv_udp_set_broadcast :: Ptr UVHandle -> CInt -> IO CInt
foreign import ccall unsafe uv_udp_set_ttl :: Ptr UVHandle -> CInt -> IO CInt

foreign import ccall unsafe hs_uv_udp_recv_start :: Ptr UVHandle -> IO CInt
foreign import ccall unsafe uv_udp_recv_stop :: Ptr UVHandle -> IO CInt
foreign import ccall unsafe hs_uv_udp_send
    :: Ptr UVHandle -> MBA# SocketAddr -> Ptr Word8 -> Int -> IO UVSlotUnSafe
foreign import ccall unsafe hs_uv_udp_send_connected
    :: Ptr UVHandle -> Ptr Word8 -> Int -> IO UVSlotUnSafe
foreign import ccall unsafe uv_udp_getsockname
    :: Ptr UVHandle -> MBA# SocketAddr -> MBA# CInt -> IO CInt
foreign import ccall unsafe uv_udp_getpeername
    :: Ptr UVHandle -> MBA# SocketAddr -> MBA# CInt -> IO CInt


--------------------------------------------------------------------------------
-- tty

-- | Terminal mode.
--
-- When in 'UV_TTY_MODE_RAW' mode, input is always available character-by-character,
-- not including modifiers. Additionally, all special processing of characters by the terminal is disabled, 
-- including echoing input characters. Note that CTRL+C will no longer cause a SIGINT when in this mode.
newtype UVTTYMode = UVTTYMode CInt
    deriving (Eq, Ord, Read, Show, FiniteBits, Bits, Storable, Num)

pattern UV_TTY_MODE_NORMAL :: UVTTYMode
pattern UV_TTY_MODE_NORMAL = UVTTYMode 0
{-# LINE 233 "Z/IO/UV/FFI.hsc" #-}
pattern UV_TTY_MODE_RAW :: UVTTYMode
pattern UV_TTY_MODE_RAW = UVTTYMode 1
{-# LINE 235 "Z/IO/UV/FFI.hsc" #-}
pattern UV_TTY_MODE_IO :: UVTTYMode
pattern UV_TTY_MODE_IO = UVTTYMode 2
{-# LINE 237 "Z/IO/UV/FFI.hsc" #-}

foreign import ccall unsafe uv_tty_init :: Ptr UVLoop -> Ptr UVHandle -> CInt -> IO CInt
foreign import ccall unsafe uv_tty_set_mode :: Ptr UVHandle -> UVTTYMode -> IO CInt
foreign import ccall unsafe uv_tty_get_winsize :: Ptr UVHandle -> MBA# CInt -> MBA# CInt -> IO CInt

--------------------------------------------------------------------------------
-- fs

newtype FileMode = FileMode CInt
    deriving (Eq, Ord, Read, Show, FiniteBits, Bits, Storable, Num)

-- | 00700 user (file owner) has read, write and execute permission
pattern S_IRWXU :: FileMode
pattern S_IRWXU = FileMode 448
{-# LINE 251 "Z/IO/UV/FFI.hsc" #-}

-- | 00400 user has read permission
pattern S_IRUSR :: FileMode
pattern S_IRUSR = FileMode 256
{-# LINE 255 "Z/IO/UV/FFI.hsc" #-}

-- | 00200 user has write permission
pattern S_IWUSR :: FileMode
pattern S_IWUSR = FileMode 128
{-# LINE 259 "Z/IO/UV/FFI.hsc" #-}

-- | 00100 user has execute permission
pattern S_IXUSR :: FileMode
pattern S_IXUSR = FileMode 64
{-# LINE 263 "Z/IO/UV/FFI.hsc" #-}

-- | 00070 group has read, write and execute permission
pattern S_IRWXG :: FileMode
pattern S_IRWXG = FileMode 56
{-# LINE 267 "Z/IO/UV/FFI.hsc" #-}

-- | 00040 group has read permission
pattern S_IRGRP :: FileMode
pattern S_IRGRP = FileMode 32
{-# LINE 271 "Z/IO/UV/FFI.hsc" #-}

-- | 00020 group has write permission
pattern S_IWGRP :: FileMode
pattern S_IWGRP = FileMode 16
{-# LINE 275 "Z/IO/UV/FFI.hsc" #-}

-- | 00010 group has execute permission
pattern S_IXGRP :: FileMode
pattern S_IXGRP = FileMode 8
{-# LINE 279 "Z/IO/UV/FFI.hsc" #-}

-- | 00007 others have read, write and execute permission
pattern S_IRWXO :: FileMode
pattern S_IRWXO = FileMode 7
{-# LINE 283 "Z/IO/UV/FFI.hsc" #-}

-- | 00004 others have read permission
pattern S_IROTH :: FileMode
pattern S_IROTH = FileMode 4
{-# LINE 287 "Z/IO/UV/FFI.hsc" #-}

-- | 00002 others have write permission
pattern S_IWOTH :: FileMode
pattern S_IWOTH = FileMode 2
{-# LINE 291 "Z/IO/UV/FFI.hsc" #-}

-- | 00001 others have execute permission
pattern S_IXOTH :: FileMode
pattern S_IXOTH = FileMode 1
{-# LINE 295 "Z/IO/UV/FFI.hsc" #-}

-- | Default mode for open, 0o666(readable and writable).
pattern DEFAULT_MODE :: FileMode
pattern DEFAULT_MODE = FileMode 0o666

-- non-threaded functions
foreign import ccall unsafe hs_uv_fs_open    :: CString -> FileFlag -> FileMode -> IO UVFD
foreign import ccall unsafe hs_uv_fs_close   :: UVFD -> IO Int
foreign import ccall unsafe hs_uv_fs_read    :: UVFD -> Ptr Word8 -> Int -> Int64 -> IO Int
foreign import ccall unsafe hs_uv_fs_write   :: UVFD -> Ptr Word8 -> Int -> Int64 -> IO Int
foreign import ccall unsafe hs_uv_fs_unlink  :: CString -> IO Int
foreign import ccall unsafe hs_uv_fs_mkdir   :: CString -> FileMode -> IO Int
foreign import ccall unsafe hs_uv_fs_rmdir   :: CString -> IO Int
foreign import ccall unsafe hs_uv_fs_mkdtemp :: CString -> Int -> CString -> IO Int

-- threaded functions
foreign import ccall unsafe hs_uv_fs_open_threaded
    :: CString -> FileFlag -> FileMode -> Ptr UVLoop -> IO UVSlotUnSafe
foreign import ccall unsafe hs_uv_fs_close_threaded
    :: UVFD -> Ptr UVLoop -> IO UVSlotUnSafe
foreign import ccall unsafe hs_uv_fs_read_threaded
    :: UVFD -> Ptr Word8 -> Int -> Int64 -> Ptr UVLoop -> IO UVSlotUnSafe
foreign import ccall unsafe hs_uv_fs_write_threaded
    :: UVFD -> Ptr Word8 -> Int -> Int64 -> Ptr UVLoop -> IO UVSlotUnSafe
foreign import ccall unsafe hs_uv_fs_unlink_threaded
    :: CString -> Ptr UVLoop -> IO UVSlotUnSafe
foreign import ccall unsafe hs_uv_fs_mkdir_threaded
    :: CString -> FileMode -> Ptr UVLoop -> IO UVSlotUnSafe
foreign import ccall unsafe hs_uv_fs_rmdir_threaded
    :: CString -> Ptr UVLoop -> IO UVSlotUnSafe
foreign import ccall unsafe hs_uv_fs_mkdtemp_threaded
    :: CString -> Int -> CString -> Ptr UVLoop -> IO UVSlotUnSafe

newtype FileFlag = FileFlag CInt
    deriving (Eq, Ord, Read, Show, FiniteBits, Bits, Storable, Num)

-- | The file is opened in append mode. Before each write, the file offset is positioned at the end of the file.
pattern O_APPEND :: FileFlag
pattern O_APPEND = FileFlag 1024
{-# LINE 334 "Z/IO/UV/FFI.hsc" #-}

-- | The file is created if it does not already exist.
pattern O_CREAT :: FileFlag
pattern O_CREAT = FileFlag 64
{-# LINE 338 "Z/IO/UV/FFI.hsc" #-}

-- | File IO is done directly to and from user-space buffers, which must be aligned. Buffer size and address should be a multiple of the physical sector size of the block device, (DO NOT USE WITH Z-IO's @BufferedIO@)
pattern O_DIRECT :: FileFlag
pattern O_DIRECT = FileFlag 16384
{-# LINE 342 "Z/IO/UV/FFI.hsc" #-}

-- | If the path is not a directory, fail the open. (Not useful on regular file)
--
-- Note 'o_DIRECTORY' is not supported on Windows.
pattern O_DIRECTORY :: FileFlag
pattern O_DIRECTORY = FileFlag 65536
{-# LINE 348 "Z/IO/UV/FFI.hsc" #-}

-- |The file is opened for synchronous IO. Write operations will complete once all data and a minimum of metadata are flushed to disk.
--
-- Note 'o_DSYNC' is supported on Windows via @FILE_FLAG_WRITE_THROUGH@.
pattern O_DSYNC :: FileFlag
pattern O_DSYNC = FileFlag 4096
{-# LINE 354 "Z/IO/UV/FFI.hsc" #-}

-- | If the 'o_CREAT' flag is set and the file already exists, fail the open.
--
-- Note In general, the behavior of 'o_EXCL' is undefined if it is used without 'o_CREAT'. There is one exception: on 
-- Linux 2.6 and later, 'o_EXCL' can be used without 'o_CREAT' if pathname refers to a block device. If the block 
-- device is in use by the system (e.g., mounted), the open will fail with the error @EBUSY@.
pattern O_EXCL :: FileFlag
pattern O_EXCL = FileFlag 128
{-# LINE 362 "Z/IO/UV/FFI.hsc" #-}

-- | Atomically obtain an exclusive lock.
--
-- Note UV_FS_O_EXLOCK is only supported on macOS and Windows.
-- (libuv: Changed in version 1.17.0: support is added for Windows.)
pattern O_EXLOCK :: FileFlag
pattern O_EXLOCK = FileFlag 0
{-# LINE 369 "Z/IO/UV/FFI.hsc" #-}

-- | Do not update the file access time when the file is read.
-- 
-- Note 'o_NOATIME' is not supported on Windows.
pattern O_NOATIME :: FileFlag
pattern O_NOATIME = FileFlag 262144
{-# LINE 375 "Z/IO/UV/FFI.hsc" #-}

-- | If the path identifies a terminal device, opening the path will not cause that terminal to become the controlling terminal for the process (if the process does not already have one). (Not sure if this flag is useful)
--
-- Note 'o_NOCTTY' is not supported on Windows.
pattern O_NOCTTY :: FileFlag
pattern O_NOCTTY = FileFlag 256
{-# LINE 381 "Z/IO/UV/FFI.hsc" #-}

-- | If the path is a symbolic link, fail the open.
--
-- Note 'o_NOFOLLOW' is not supported on Windows.
pattern O_NOFOLLOW :: FileFlag
pattern O_NOFOLLOW = FileFlag 131072
{-# LINE 387 "Z/IO/UV/FFI.hsc" #-}

-- | Open the file in nonblocking mode if possible. (Definitely not useful in Z-IO)
--
-- Note 'o_NONBLOCK' is not supported on Windows. (Not useful on regular file anyway)
pattern O_NONBLOCK :: FileFlag
pattern O_NONBLOCK = FileFlag 2048
{-# LINE 393 "Z/IO/UV/FFI.hsc" #-}

-- | Access is intended to be random. The system can use this as a hint to optimize file caching.
-- 
-- Note 'o_RANDOM' is only supported on Windows via @FILE_FLAG_RANDOM_ACCESS@.
pattern O_RANDOM :: FileFlag
pattern O_RANDOM = FileFlag 0
{-# LINE 399 "Z/IO/UV/FFI.hsc" #-}

-- | Open the file for read-only access.
pattern O_RDONLY :: FileFlag
pattern O_RDONLY = FileFlag 0
{-# LINE 403 "Z/IO/UV/FFI.hsc" #-}

-- | Open the file for read-write access.
pattern O_RDWR :: FileFlag
pattern O_RDWR = FileFlag 2
{-# LINE 407 "Z/IO/UV/FFI.hsc" #-}


-- | Access is intended to be sequential from beginning to end. The system can use this as a hint to optimize file caching.
-- 
-- Note 'o_SEQUENTIAL' is only supported on Windows via @FILE_FLAG_SEQUENTIAL_SCAN@.
pattern O_SEQUENTIAL :: FileFlag
pattern O_SEQUENTIAL = FileFlag 0
{-# LINE 414 "Z/IO/UV/FFI.hsc" #-}

-- | The file is temporary and should not be flushed to disk if possible.
--
-- Note 'o_SHORT_LIVED' is only supported on Windows via @FILE_ATTRIBUTE_TEMPORARY@.
pattern O_SHORT_LIVED :: FileFlag
pattern O_SHORT_LIVED = FileFlag 0
{-# LINE 420 "Z/IO/UV/FFI.hsc" #-}

-- | Open the symbolic link itself rather than the resource it points to.
pattern O_SYMLINK :: FileFlag
pattern O_SYMLINK = FileFlag 0
{-# LINE 424 "Z/IO/UV/FFI.hsc" #-}

-- | The file is opened for synchronous IO. Write operations will complete once all data and all metadata are flushed to disk.
--
-- Note 'o_SYNC' is supported on Windows via @FILE_FLAG_WRITE_THROUGH@.
pattern O_SYNC :: FileFlag
pattern O_SYNC = FileFlag 1052672
{-# LINE 430 "Z/IO/UV/FFI.hsc" #-}

-- | The file is temporary and should not be flushed to disk if possible.
--
-- Note 'o_TEMPORARY' is only supported on Windows via @FILE_ATTRIBUTE_TEMPORARY@.
pattern O_TEMPORARY :: FileFlag
pattern O_TEMPORARY = FileFlag 0
{-# LINE 436 "Z/IO/UV/FFI.hsc" #-}

-- | If the file exists and is a regular file, and the file is opened successfully for write access, its length shall be truncated to zero.
pattern O_TRUNC :: FileFlag
pattern O_TRUNC = FileFlag 512
{-# LINE 440 "Z/IO/UV/FFI.hsc" #-}

-- | Open the file for write-only access.
pattern O_WRONLY :: FileFlag
pattern O_WRONLY = FileFlag 1
{-# LINE 444 "Z/IO/UV/FFI.hsc" #-}


{-# LINE 448 "Z/IO/UV/FFI.hsc" #-}
newtype UVDirEntType = UVDirEntType CChar

{-# LINE 450 "Z/IO/UV/FFI.hsc" #-}
    deriving (Eq, Ord, Read, Show, FiniteBits, Bits, Storable, Num)

data DirEntType
    = DirEntUnknown
    | DirEntFile
    | DirEntDir
    | DirEntLink
    | DirEntFIFO
    | DirEntSocket
    | DirEntChar
    | DirEntBlock
  deriving (Read, Show, Eq, Ord, Generic)

fromUVDirEntType :: UVDirEntType -> DirEntType
fromUVDirEntType t
    | t == uV__DT_FILE   = DirEntFile
    | t == uV__DT_DIR    = DirEntDir
    | t == uV__DT_LINK   = DirEntLink
    | t == uV__DT_FIFO   = DirEntFIFO
    | t == uV__DT_SOCKET = DirEntSocket
    | t == uV__DT_CHAR   = DirEntChar
    | t == uV__DT_BLOCK  = DirEntBlock
    | otherwise          = DirEntUnknown

uV__DT_FILE     :: UVDirEntType
uV__DT_FILE     = UVDirEntType 8
uV__DT_DIR      :: UVDirEntType
uV__DT_DIR      = UVDirEntType 4
uV__DT_LINK     :: UVDirEntType
uV__DT_LINK     = UVDirEntType 10
uV__DT_FIFO     :: UVDirEntType
uV__DT_FIFO     = UVDirEntType 1
uV__DT_SOCKET   :: UVDirEntType
uV__DT_SOCKET   = UVDirEntType 12
uV__DT_CHAR     :: UVDirEntType
uV__DT_CHAR     = UVDirEntType 2
uV__DT_BLOCK    :: UVDirEntType
uV__DT_BLOCK    = UVDirEntType 6

{-# LINE 482 "Z/IO/UV/FFI.hsc" #-}

data UVDirEnt

peekUVDirEnt :: Ptr UVDirEnt -> IO (CString, UVDirEntType)

{-# LINE 487 "Z/IO/UV/FFI.hsc" #-}
peekUVDirEnt p = (,) ((\hsc_ptr -> hsc_ptr `plusPtr` 19) p) <$> ((\hsc_ptr -> peekByteOff hsc_ptr 18) p)
{-# LINE 488 "Z/IO/UV/FFI.hsc" #-}

{-# LINE 491 "Z/IO/UV/FFI.hsc" #-}

foreign import ccall unsafe hs_uv_fs_scandir_cleanup
    :: Ptr (Ptr UVDirEnt) -> Int -> IO ()
foreign import ccall unsafe hs_uv_fs_scandir
    :: CString -> MBA# (Ptr UVDirEnt) -> IO Int
foreign import ccall unsafe hs_uv_fs_scandir_extra_cleanup
    :: Ptr (Ptr (Ptr UVDirEnt)) -> Int -> IO ()
foreign import ccall unsafe hs_uv_fs_scandir_threaded
    :: CString -> Ptr (Ptr (Ptr UVDirEnt)) -> Ptr UVLoop -> IO UVSlotUnSafe

data UVTimeSpec = UVTimeSpec
    { uvtSecond     :: {-# UNPACK #-} !CLong
    , uvtNanoSecond :: {-# UNPACK #-} !CLong
    } deriving (Show, Read, Eq, Ord, Generic)

instance Storable UVTimeSpec where
    sizeOf _  = (16)
{-# LINE 508 "Z/IO/UV/FFI.hsc" #-}
    alignment _ = 8
{-# LINE 509 "Z/IO/UV/FFI.hsc" #-}
    peek p = UVTimeSpec <$> ((\hsc_ptr -> peekByteOff hsc_ptr 0) p)
{-# LINE 510 "Z/IO/UV/FFI.hsc" #-}
                        <*> ((\hsc_ptr -> peekByteOff hsc_ptr 8) p)
{-# LINE 511 "Z/IO/UV/FFI.hsc" #-}
    poke p (UVTimeSpec sec nsec) = do
        ((\hsc_ptr -> pokeByteOff hsc_ptr 0) p sec)
{-# LINE 513 "Z/IO/UV/FFI.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 8) p nsec)
{-# LINE 514 "Z/IO/UV/FFI.hsc" #-}

data UVStat = UVStat
    { stDev      :: {-# UNPACK #-} !Word64
    , stMode     :: {-# UNPACK #-} !Word64
    , stNlink    :: {-# UNPACK #-} !Word64
    , stUid      :: {-# UNPACK #-} !Word64
    , stGid      :: {-# UNPACK #-} !Word64
    , stRdev     :: {-# UNPACK #-} !Word64
    , stIno      :: {-# UNPACK #-} !Word64
    , stSize     :: {-# UNPACK #-} !Word64
    , stBlksize  :: {-# UNPACK #-} !Word64
    , stBlocks   :: {-# UNPACK #-} !Word64
    , stFlags    :: {-# UNPACK #-} !Word64
    , stGen      :: {-# UNPACK #-} !Word64
    , stAtim     :: {-# UNPACK #-} !UVTimeSpec
    , stMtim     :: {-# UNPACK #-} !UVTimeSpec
    , stCtim     :: {-# UNPACK #-} !UVTimeSpec
    , stBirthtim :: {-# UNPACK #-} !UVTimeSpec
    } deriving (Show, Read, Eq, Ord, Generic)

uvStatSize :: Int
uvStatSize = (160)
{-# LINE 536 "Z/IO/UV/FFI.hsc" #-}

peekUVStat :: Ptr UVStat -> IO UVStat
peekUVStat p = UVStat
    <$> ((\hsc_ptr -> peekByteOff hsc_ptr 0) p)
{-# LINE 540 "Z/IO/UV/FFI.hsc" #-}
    <*> ((\hsc_ptr -> peekByteOff hsc_ptr 8) p)
{-# LINE 541 "Z/IO/UV/FFI.hsc" #-}
    <*> ((\hsc_ptr -> peekByteOff hsc_ptr 16) p)
{-# LINE 542 "Z/IO/UV/FFI.hsc" #-}
    <*> ((\hsc_ptr -> peekByteOff hsc_ptr 24) p)
{-# LINE 543 "Z/IO/UV/FFI.hsc" #-}
    <*> ((\hsc_ptr -> peekByteOff hsc_ptr 32) p)
{-# LINE 544 "Z/IO/UV/FFI.hsc" #-}
    <*> ((\hsc_ptr -> peekByteOff hsc_ptr 40) p)
{-# LINE 545 "Z/IO/UV/FFI.hsc" #-}
    <*> ((\hsc_ptr -> peekByteOff hsc_ptr 48) p)
{-# LINE 546 "Z/IO/UV/FFI.hsc" #-}
    <*> ((\hsc_ptr -> peekByteOff hsc_ptr 56) p)
{-# LINE 547 "Z/IO/UV/FFI.hsc" #-}
    <*> ((\hsc_ptr -> peekByteOff hsc_ptr 64) p)
{-# LINE 548 "Z/IO/UV/FFI.hsc" #-}
    <*> ((\hsc_ptr -> peekByteOff hsc_ptr 72) p)
{-# LINE 549 "Z/IO/UV/FFI.hsc" #-}
    <*> ((\hsc_ptr -> peekByteOff hsc_ptr 80) p)
{-# LINE 550 "Z/IO/UV/FFI.hsc" #-}
    <*> ((\hsc_ptr -> peekByteOff hsc_ptr 88) p)
{-# LINE 551 "Z/IO/UV/FFI.hsc" #-}
    <*> ((\hsc_ptr -> peekByteOff hsc_ptr 96) p)
{-# LINE 552 "Z/IO/UV/FFI.hsc" #-}
    <*> ((\hsc_ptr -> peekByteOff hsc_ptr 112) p)
{-# LINE 553 "Z/IO/UV/FFI.hsc" #-}
    <*> ((\hsc_ptr -> peekByteOff hsc_ptr 128) p)
{-# LINE 554 "Z/IO/UV/FFI.hsc" #-}
    <*> ((\hsc_ptr -> peekByteOff hsc_ptr 144) p)
{-# LINE 555 "Z/IO/UV/FFI.hsc" #-}

foreign import ccall unsafe hs_uv_fs_stat :: CString -> Ptr UVStat -> IO Int
foreign import ccall unsafe hs_uv_fs_fstat :: UVFD -> Ptr UVStat -> IO Int
foreign import ccall unsafe hs_uv_fs_lstat :: CString -> Ptr UVStat -> IO Int
foreign import ccall unsafe hs_uv_fs_rename :: CString -> CString -> IO Int
foreign import ccall unsafe hs_uv_fs_fsync :: UVFD -> IO Int
foreign import ccall unsafe hs_uv_fs_fdatasync :: UVFD -> IO Int
foreign import ccall unsafe hs_uv_fs_ftruncate :: UVFD -> Int64 -> IO Int

foreign import ccall unsafe hs_uv_fs_stat_threaded
    :: CString -> Ptr UVStat -> Ptr UVLoop -> IO UVSlotUnSafe
foreign import ccall unsafe hs_uv_fs_fstat_threaded
    :: UVFD -> Ptr UVStat -> Ptr UVLoop -> IO UVSlotUnSafe
foreign import ccall unsafe hs_uv_fs_lstat_threaded
    :: CString -> Ptr UVStat -> Ptr UVLoop -> IO UVSlotUnSafe
foreign import ccall unsafe hs_uv_fs_rename_threaded
    :: CString -> CString -> Ptr UVLoop -> IO UVSlotUnSafe
foreign import ccall unsafe hs_uv_fs_fsync_threaded
    :: UVFD -> Ptr UVLoop -> IO UVSlotUnSafe
foreign import ccall unsafe hs_uv_fs_fdatasync_threaded
    :: UVFD -> Ptr UVLoop -> IO UVSlotUnSafe
foreign import ccall unsafe hs_uv_fs_ftruncate_threaded
    :: UVFD -> Int64 -> Ptr UVLoop -> IO UVSlotUnSafe

-- | Flags control copying.
-- 
--   * 'COPYFILE_EXCL': If present, uv_fs_copyfile() will fail with UV_EEXIST if the destination path already exists. The default behavior is to overwrite the destination if it exists.
--   * 'COPYFILE_FICLONE': If present, uv_fs_copyfile() will attempt to create a copy-on-write reflink. If the underlying platform does not support copy-on-write, then a fallback copy mechanism is used.
-- 
newtype UVCopyFileFlag = UVCopyFileFlag CInt
    deriving (Eq, Ord, Read, Show, FiniteBits, Bits, Storable, Num)

pattern COPYFILE_DEFAULT :: UVCopyFileFlag
pattern COPYFILE_DEFAULT = UVCopyFileFlag 0

pattern COPYFILE_EXCL :: UVCopyFileFlag
pattern COPYFILE_EXCL = UVCopyFileFlag 1
{-# LINE 592 "Z/IO/UV/FFI.hsc" #-}

pattern COPYFILE_FICLONE :: UVCopyFileFlag

{-# LINE 595 "Z/IO/UV/FFI.hsc" #-}
pattern COPYFILE_FICLONE = UVCopyFileFlag 2
{-# LINE 596 "Z/IO/UV/FFI.hsc" #-}

{-# LINE 599 "Z/IO/UV/FFI.hsc" #-}

foreign import ccall unsafe hs_uv_fs_copyfile :: CString -> CString -> UVCopyFileFlag -> IO Int
foreign import ccall unsafe hs_uv_fs_copyfile_threaded
    :: CString -> CString -> UVCopyFileFlag -> Ptr UVLoop -> IO UVSlotUnSafe

newtype UVAccessMode = UVAccessMode CInt
    deriving (Eq, Ord, Read, Show, FiniteBits, Bits, Storable, Num)

pattern F_OK :: UVAccessMode
pattern F_OK = UVAccessMode 0
{-# LINE 609 "Z/IO/UV/FFI.hsc" #-}
pattern R_OK :: UVAccessMode
pattern R_OK = UVAccessMode 4
{-# LINE 611 "Z/IO/UV/FFI.hsc" #-}
pattern W_OK :: UVAccessMode
pattern W_OK = UVAccessMode 2
{-# LINE 613 "Z/IO/UV/FFI.hsc" #-}
pattern X_OK :: UVAccessMode
pattern X_OK = UVAccessMode 1
{-# LINE 615 "Z/IO/UV/FFI.hsc" #-}

data AccessResult = NoExistence | NoPermission | AccessOK deriving (Show, Eq, Ord)

foreign import ccall unsafe hs_uv_fs_access :: CString -> UVAccessMode -> IO Int
foreign import ccall unsafe hs_uv_fs_access_threaded
    :: CString -> UVAccessMode -> Ptr UVLoop -> IO UVSlotUnSafe

foreign import ccall unsafe hs_uv_fs_chmod :: CString -> FileMode -> IO Int
foreign import ccall unsafe hs_uv_fs_chmod_threaded
    :: CString -> FileMode -> Ptr UVLoop -> IO UVSlotUnSafe

foreign import ccall unsafe hs_uv_fs_fchmod :: UVFD -> FileMode -> IO Int
foreign import ccall unsafe hs_uv_fs_fchmod_threaded
    :: UVFD -> FileMode -> Ptr UVLoop -> IO UVSlotUnSafe

foreign import ccall unsafe hs_uv_fs_utime :: CString -> Double -> Double -> IO Int
foreign import ccall unsafe hs_uv_fs_utime_threaded
    :: CString -> Double -> Double -> Ptr UVLoop -> IO UVSlotUnSafe

foreign import ccall unsafe hs_uv_fs_futime :: UVFD -> Double -> Double -> IO Int
foreign import ccall unsafe hs_uv_fs_futime_threaded
    :: UVFD -> Double -> Double -> Ptr UVLoop -> IO UVSlotUnSafe

newtype UVSymlinkFlag = UVSymlinkFlag CInt
    deriving (Eq, Ord, Read, Show, FiniteBits, Bits, Storable, Num)

pattern SYMLINK_DEFAULT :: UVSymlinkFlag
pattern SYMLINK_DEFAULT = UVSymlinkFlag 0

pattern SYMLINK_DIR :: UVSymlinkFlag
pattern SYMLINK_DIR = UVSymlinkFlag 1
{-# LINE 646 "Z/IO/UV/FFI.hsc" #-}

pattern SYMLINK_JUNCTION :: UVSymlinkFlag
pattern SYMLINK_JUNCTION = UVSymlinkFlag 2
{-# LINE 649 "Z/IO/UV/FFI.hsc" #-}

foreign import ccall unsafe hs_uv_fs_link :: CString -> CString -> IO Int
foreign import ccall unsafe hs_uv_fs_link_threaded
    :: CString -> CString -> Ptr UVLoop -> IO UVSlotUnSafe

foreign import ccall unsafe hs_uv_fs_symlink :: CString -> CString -> UVSymlinkFlag -> IO Int
foreign import ccall unsafe hs_uv_fs_symlink_threaded
    :: CString -> CString -> UVSymlinkFlag -> Ptr UVLoop -> IO UVSlotUnSafe

-- readlink and realpath share the same cleanup and callback
foreign import ccall unsafe hs_uv_fs_readlink_cleanup
    :: CString -> IO ()
foreign import ccall unsafe hs_uv_fs_readlink
    :: CString -> MBA# CString -> IO Int
foreign import ccall unsafe hs_uv_fs_realpath
    :: CString -> MBA# CString -> IO Int
foreign import ccall unsafe hs_uv_fs_readlink_extra_cleanup
    :: Ptr CString -> IO ()
foreign import ccall unsafe hs_uv_fs_readlink_threaded
    :: CString -> Ptr CString -> Ptr UVLoop -> IO UVSlotUnSafe
foreign import ccall unsafe hs_uv_fs_realpath_threaded
    :: CString -> Ptr CString -> Ptr UVLoop -> IO UVSlotUnSafe

--------------------------------------------------------------------------------
-- misc

newtype UVHandleType = UVHandleType CInt deriving (Eq, Ord, Read, Show, Storable)

pattern UV_UNKNOWN_HANDLE :: UVHandleType
pattern UV_UNKNOWN_HANDLE = UVHandleType 0
{-# LINE 679 "Z/IO/UV/FFI.hsc" #-}
pattern UV_ASYNC :: UVHandleType
pattern UV_ASYNC = UVHandleType 1
{-# LINE 681 "Z/IO/UV/FFI.hsc" #-}
pattern UV_CHECK :: UVHandleType
pattern UV_CHECK = UVHandleType 2
{-# LINE 683 "Z/IO/UV/FFI.hsc" #-}
pattern UV_FS_EVENT :: UVHandleType
pattern UV_FS_EVENT = UVHandleType 3
{-# LINE 685 "Z/IO/UV/FFI.hsc" #-}
pattern UV_FS_POLL :: UVHandleType
pattern UV_FS_POLL = UVHandleType 4
{-# LINE 687 "Z/IO/UV/FFI.hsc" #-}
pattern UV_HANDLE :: UVHandleType
pattern UV_HANDLE = UVHandleType 5
{-# LINE 689 "Z/IO/UV/FFI.hsc" #-}
pattern UV_IDLE :: UVHandleType
pattern UV_IDLE = UVHandleType 6
{-# LINE 691 "Z/IO/UV/FFI.hsc" #-}
pattern UV_NAMED_PIPE :: UVHandleType
pattern UV_NAMED_PIPE = UVHandleType 7
{-# LINE 693 "Z/IO/UV/FFI.hsc" #-}
pattern UV_POLL :: UVHandleType
pattern UV_POLL = UVHandleType 8
{-# LINE 695 "Z/IO/UV/FFI.hsc" #-}
pattern UV_PREPARE :: UVHandleType
pattern UV_PREPARE = UVHandleType 9
{-# LINE 697 "Z/IO/UV/FFI.hsc" #-}
pattern UV_PROCESS :: UVHandleType
pattern UV_PROCESS = UVHandleType 10
{-# LINE 699 "Z/IO/UV/FFI.hsc" #-}
pattern UV_STREAM :: UVHandleType
pattern UV_STREAM = UVHandleType 11
{-# LINE 701 "Z/IO/UV/FFI.hsc" #-}
pattern UV_TCP :: UVHandleType
pattern UV_TCP = UVHandleType 12
{-# LINE 703 "Z/IO/UV/FFI.hsc" #-}
pattern UV_TIMER :: UVHandleType
pattern UV_TIMER = UVHandleType 13
{-# LINE 705 "Z/IO/UV/FFI.hsc" #-}
pattern UV_TTY :: UVHandleType
pattern UV_TTY = UVHandleType 14
{-# LINE 707 "Z/IO/UV/FFI.hsc" #-}
pattern UV_UDP :: UVHandleType
pattern UV_UDP = UVHandleType 15
{-# LINE 709 "Z/IO/UV/FFI.hsc" #-}
pattern UV_SIGNAL :: UVHandleType
pattern UV_SIGNAL = UVHandleType 16
{-# LINE 711 "Z/IO/UV/FFI.hsc" #-}
pattern UV_FILE :: UVHandleType
pattern UV_FILE = UVHandleType 17
{-# LINE 713 "Z/IO/UV/FFI.hsc" #-}

foreign import ccall unsafe uv_guess_handle :: UVFD -> IO UVHandleType