-- |
--   Copyright   :  (c) Sam Truzjan 2013
--   License     :  BSD3
--   Maintainer  :  pxqr.sta@gmail.com
--   Stability   :  experimental
--   Portability :  portable
--
--   Internal definitions; do not export this module.
--
module System.UDev.Types
       ( Ref (..)
       , UDevChild (..)

       , UDev   (..)
       , Device (..)
       , Enumerate (..)
       , HWDB   (..)
       , List   (..), nil
       , Queue  (..)
       ) where

import Foreign

{-----------------------------------------------------------------------
--  Classes
-----------------------------------------------------------------------}

class Ref a where
  ref   :: a -> IO a
  unref :: a -> IO a

-- | Family of udev resources.
class UDevChild a where
  -- | Get the context a resource belong to.
  getUDev :: a -> UDev

{-----------------------------------------------------------------------
--  UDev
-----------------------------------------------------------------------}

-- | Opaque object representing the library context.
newtype UDev = UDev (Ptr UDev)


instance UDevChild UDev where
  getUDev :: UDev -> UDev
getUDev = UDev -> UDev
forall a. a -> a
id

foreign import ccall unsafe "udev_ref"
  c_ref :: UDev -> IO UDev

foreign import ccall unsafe "udev_unref"
  c_unref :: UDev -> IO UDev

instance Ref UDev where
  ref :: UDev -> IO UDev
ref   = UDev -> IO UDev
c_ref
  unref :: UDev -> IO UDev
unref = UDev -> IO UDev
c_unref

{-----------------------------------------------------------------------
--  Device
-----------------------------------------------------------------------}

-- | Opaque object representing one kernel sys device.
newtype Device = Device { Device -> Ptr Device
getDevice :: Ptr Device }

foreign import ccall unsafe "udev_device_ref"
  c_deviceRef :: Device -> IO Device

foreign import ccall unsafe "udev_device_unref"
  c_deviceUnref :: Device -> IO Device

instance Ref Device where
  ref :: Device -> IO Device
ref   = Device -> IO Device
c_deviceRef
  unref :: Device -> IO Device
unref = Device -> IO Device
c_deviceUnref

foreign import ccall unsafe "udev_device_get_udev"
  c_getUDev :: Device -> UDev

instance UDevChild Device where
  getUDev :: Device -> UDev
getUDev = Device -> UDev
c_getUDev

{-----------------------------------------------------------------------
--  Enumerate
-----------------------------------------------------------------------}

-- | Opaque object representing one device lookup/sort context.
newtype Enumerate = Enumerate (Ptr Enumerate)

foreign import ccall unsafe "udev_enumerate_ref"
  c_EnumerateRef :: Enumerate -> IO Enumerate

foreign import ccall unsafe "udev_enumerate_unref"
  c_EnumerateUnref :: Enumerate -> IO Enumerate

instance Ref Enumerate where
  ref :: Enumerate -> IO Enumerate
ref   = Enumerate -> IO Enumerate
c_EnumerateRef
  unref :: Enumerate -> IO Enumerate
unref = Enumerate -> IO Enumerate
c_EnumerateUnref

foreign import ccall unsafe "udev_enumerate_get_udev"
  c_EnumerateGetUDev :: Enumerate -> UDev

instance UDevChild Enumerate where
  getUDev :: Enumerate -> UDev
getUDev = Enumerate -> UDev
c_EnumerateGetUDev

{-----------------------------------------------------------------------
--  HWDB
-----------------------------------------------------------------------}

-- | Opaque object representing the hardware database.
newtype HWDB = HWDB (Ptr HWDB)

foreign import ccall unsafe "udev_hwdb_ref"
  c_HWDBRef :: HWDB -> IO HWDB

foreign import ccall unsafe "udev_hwdb_unref"
  c_HWDBUnref :: HWDB -> IO HWDB

instance Ref HWDB where
  ref :: HWDB -> IO HWDB
ref   = HWDB -> IO HWDB
c_HWDBRef
  unref :: HWDB -> IO HWDB
unref = HWDB -> IO HWDB
c_HWDBUnref

{-----------------------------------------------------------------------
--  List
-----------------------------------------------------------------------}

-- TODO newtype List name value

-- | Opaque object representing one entry in a list. An entry contains
-- contains a name, and optionally a value.
--
newtype List = List (Ptr List)
               deriving List -> List -> Bool
(List -> List -> Bool) -> (List -> List -> Bool) -> Eq List
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: List -> List -> Bool
$c/= :: List -> List -> Bool
== :: List -> List -> Bool
$c== :: List -> List -> Bool
Eq

nil :: List
nil :: List
nil = Ptr List -> List
List Ptr List
forall a. Ptr a
nullPtr

{-----------------------------------------------------------------------
--  Queue
-----------------------------------------------------------------------}

-- | Opaque object representing the current event queue in the udev
-- daemon.
newtype Queue = Queue { Queue -> Ptr Queue
getQueue :: Ptr Queue }

foreign import ccall unsafe "udev_queue_ref"
  c_queueRef :: Queue -> IO Queue

foreign import ccall unsafe "udev_queue_unref"
  c_queueUnref :: Queue -> IO Queue

instance Ref Queue where
  ref :: Queue -> IO Queue
ref   = Queue -> IO Queue
c_queueRef
  unref :: Queue -> IO Queue
unref = Queue -> IO Queue
c_queueUnref