{-# LINE 1 "src/System/SysInfo.hsc" #-}
{-#LANGUAGE CPP#-}
{-# LINE 2 "src/System/SysInfo.hsc" #-}
{-#LANGUAGE ForeignFunctionInterface#-}
{-#LANGUAGE ScopedTypeVariables#-}
{-#LANGUAGE RecordWildCards#-}

module System.SysInfo
  ( 

   -- * Usage
   -- $usage

    sysInfo
  , SysInfo(..)
  , Loads(..)
  ) where


{-# LINE 18 "src/System/SysInfo.hsc" #-}

{-# LINE 19 "src/System/SysInfo.hsc" #-}

{-# LINE 20 "src/System/SysInfo.hsc" #-}

import Foreign.C
import Foreign.Ptr
import Foreign.C.Error
import Foreign.Storable
import Foreign.Marshal.Alloc

-- $usage
--
-- @
-- λ> import System.SysInfo
-- λ> val <- sysInfo
-- λ> either (\_ -> "sysinfo failed") show val
-- "SysInfo {uptime = 121149, loads = Loads {sloads = [91200,80736,82592]}, totalram = 12286611456, freeram = 967655424, sharedram = 63033344, bufferram = 838983680, totalswap = 8261726208, freeswap = 8259276800, procs = 418, totalhigh = 0, freehigh = 0, memUnit = 1}"
-- @


{-# LINE 39 "src/System/SysInfo.hsc" #-}

-- | Data type representing system informating
data SysInfo = SysInfo
  { uptime :: CLong -- ^ Seconds since boot
  , loads :: Loads -- ^ 1, 5, and 15 minute load averages 
  , totalram :: CULong -- ^ Total usable main memory size 
  , freeram :: CULong -- ^ Available memory size 
  , sharedram :: CULong -- ^ Amount of shared memory 
  , bufferram :: CULong -- ^ Memory used by buffers
  , totalswap :: CULong -- ^ Total swap space size
  , freeswap :: CULong -- ^ swap space still available
  , procs :: CUShort -- ^ Number of current processes
  , totalhigh :: CULong -- ^ Total high memory size
  , freehigh :: CULong -- ^ Available high memory size
  , memUnit :: CUInt -- ^ Memory unit size in bytes
  } deriving (Show, Eq, Ord)

newtype Loads = Loads
  { sloads :: [CULong]
  } deriving (Show, Eq, Ord)

instance Storable Loads where
  sizeOf _ = (sizeOf (undefined :: CULong)) * 3
  alignment _ = alignment (undefined :: CULong)
  peek ptr = do
    (vals :: [CULong]) <- mapM (peekElemOff ptr') index
    return $ Loads vals
    where
      ptr' = castPtr ptr
      index = [0, 1, 2]
  poke ptr (Loads val) = mapM_ (\(v, i) -> pokeElemOff ptr' i v) (zip val index)
    where
      (ptr' :: Ptr CULong) = castPtr ptr
      index = [0, 1, 2]


{-# LINE 75 "src/System/SysInfo.hsc" #-}
instance Storable SysInfo where
  sizeOf _ = ((112))
{-# LINE 77 "src/System/SysInfo.hsc" #-}
  alignment _ = ((8))
{-# LINE 78 "src/System/SysInfo.hsc" #-}
  peek ptr = do
    uptime <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) ptr
{-# LINE 80 "src/System/SysInfo.hsc" #-}
    loads <- ((\hsc_ptr -> peekByteOff hsc_ptr 8)) ptr
{-# LINE 81 "src/System/SysInfo.hsc" #-}
    totalram <- ((\hsc_ptr -> peekByteOff hsc_ptr 32)) ptr
{-# LINE 82 "src/System/SysInfo.hsc" #-}
    freeram <- ((\hsc_ptr -> peekByteOff hsc_ptr 40)) ptr
{-# LINE 83 "src/System/SysInfo.hsc" #-}
    sharedram <- ((\hsc_ptr -> peekByteOff hsc_ptr 48)) ptr
{-# LINE 84 "src/System/SysInfo.hsc" #-}
    bufferram <- ((\hsc_ptr -> peekByteOff hsc_ptr 56)) ptr
{-# LINE 85 "src/System/SysInfo.hsc" #-}
    totalswap <- ((\hsc_ptr -> peekByteOff hsc_ptr 64)) ptr
{-# LINE 86 "src/System/SysInfo.hsc" #-}
    freeswap <- ((\hsc_ptr -> peekByteOff hsc_ptr 72)) ptr
{-# LINE 87 "src/System/SysInfo.hsc" #-}
    procs <- ((\hsc_ptr -> peekByteOff hsc_ptr 80)) ptr
{-# LINE 88 "src/System/SysInfo.hsc" #-}
    totalhigh <- ((\hsc_ptr -> peekByteOff hsc_ptr 88)) ptr
{-# LINE 89 "src/System/SysInfo.hsc" #-}
    freehigh <- ((\hsc_ptr -> peekByteOff hsc_ptr 96)) ptr
{-# LINE 90 "src/System/SysInfo.hsc" #-}
    memUnit <- ((\hsc_ptr -> peekByteOff hsc_ptr 104)) ptr
{-# LINE 91 "src/System/SysInfo.hsc" #-}
    return $
      SysInfo
      { ..
      }
  poke ptr (SysInfo {..}) = do
    ((\hsc_ptr -> pokeByteOff hsc_ptr 0)) ptr uptime
{-# LINE 97 "src/System/SysInfo.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 8)) ptr loads
{-# LINE 98 "src/System/SysInfo.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 32)) ptr totalram
{-# LINE 99 "src/System/SysInfo.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 40)) ptr freeram
{-# LINE 100 "src/System/SysInfo.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 48)) ptr sharedram
{-# LINE 101 "src/System/SysInfo.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 56)) ptr bufferram
{-# LINE 102 "src/System/SysInfo.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 64)) ptr totalswap
{-# LINE 103 "src/System/SysInfo.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 72)) ptr freeswap
{-# LINE 104 "src/System/SysInfo.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 80)) ptr procs
{-# LINE 105 "src/System/SysInfo.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 88)) ptr totalhigh
{-# LINE 106 "src/System/SysInfo.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 96)) ptr freehigh
{-# LINE 107 "src/System/SysInfo.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 104)) ptr memUnit
{-# LINE 108 "src/System/SysInfo.hsc" #-}

foreign import ccall safe "sysinfo" c_sysinfo ::
               Ptr SysInfo -> IO CInt

-- | Function for getting system information. Internally it uses the
-- Linux system call sysinfo to get the system statistics.
sysInfo :: IO (Either Errno SysInfo)
sysInfo = do
  (sptr :: Ptr SysInfo) <- malloc
  res <- c_sysinfo sptr
  if (res == 0)
    then do
      val <- peek sptr
      free sptr
      return $ Right val
    else do
      free sptr
      err <- getErrno
      return $ Left err

{-# LINE 133 "src/System/SysInfo.hsc" #-}