{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}

module Network.Monitoring.Riemann.TCPClient where

import Control.Monad.IO.Class (MonadIO, liftIO)
import qualified Data.Sequence as Seq
import Network.Monitoring.Riemann.Client (Client, close, sendEvent)
import qualified Network.Monitoring.Riemann.TCP as TCP
import Network.Monitoring.Riemann.TCP (Port, TCPConnection)
import Network.Socket (HostName)

newtype TCPClient =
  TCPClient TCPConnection

{-|
    A new TCPClient

    The TCPClient is a 'Client' that will send single events synchronously over TCP.

    Current time and host name will be set if not provided.

    '''Note''': We never use IPv6 address resolved for given hostname.
-}
tcpClient :: HostName -> Port -> IO TCPClient
tcpClient :: HostName -> Port -> IO TCPClient
tcpClient HostName
h Port
p = do
  TCPConnection
c <- HostName -> Port -> IO TCPConnection
TCP.tcpConnection HostName
h Port
p
  TCPClient -> IO TCPClient
forall (f :: * -> *) a. Applicative f => a -> f a
pure (TCPClient -> IO TCPClient) -> TCPClient -> IO TCPClient
forall a b. (a -> b) -> a -> b
$ TCPConnection -> TCPClient
TCPClient TCPConnection
c

instance MonadIO m => Client m TCPClient where
  sendEvent :: TCPClient -> Event -> m ()
sendEvent (TCPClient TCPConnection
connection) Event
event =
    IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ TCPConnection -> Seq Event -> IO ()
TCP.sendEvents TCPConnection
connection (Seq Event -> IO ()) -> Seq Event -> IO ()
forall a b. (a -> b) -> a -> b
$ Event -> Seq Event
forall a. a -> Seq a
Seq.singleton Event
event
  close :: TCPClient -> m ()
close TCPClient
_ = IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ HostName -> IO ()
forall a. Show a => a -> IO ()
print HostName
"close"