-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


@package ntp-client
@version 0.0.1

module Network.NTP.Client

-- | Setup a NtpClient and run an application that uses provided
--   <a>NtpClient</a>. The <a>NtpClient</a> is terminated when the callback
--   returns. The application can <a>waitCatch</a> on <a>ntpThread</a>.
withNtpClient :: IOManager -> Tracer IO NtpTrace -> NtpSettings -> (NtpClient -> IO a) -> IO a

-- | Settings of the ntp client.
data NtpSettings
NtpSettings :: [String] -> Int -> Microsecond -> Microsecond -> NtpSettings

-- | List of server addresses. At least three servers are needed.
[ntpServers] :: NtpSettings -> [String]

-- | Minimum number of results to compute the offset, this should be less
--   or equal to the length of <a>ntpServers</a> (we send a single
--   <tt>tnp</tt> packet / query to a each server, if the dns name resolves
--   to many addresses we pick the first one).
[ntpRequiredNumberOfResults] :: NtpSettings -> Int

-- | Timeout for receiving a response from an <tt>ntp</tt> server.
[ntpResponseTimeout] :: NtpSettings -> Microsecond

-- | How long to wait between two rounds of requests. This should be set to
--   something of an order of one hour, <tt>ntp</tt> servers should not be
--   abused.
[ntpPollDelay] :: NtpSettings -> Microsecond

-- | <a>NtpClient</a> which recieves updates of the wall clcok drift every
--   <a>ntpPollDelay</a>. It also allows to force engaging in ntp protocol.
data NtpClient
NtpClient :: STM NtpStatus -> IO NtpStatus -> Async Void -> NtpClient

-- | Query the current NTP status.
[ntpGetStatus] :: NtpClient -> STM NtpStatus

-- | Force to update the ntp state, unless an ntp query is already running.
--   This is a blocking operation.
[ntpQueryBlocking] :: NtpClient -> IO NtpStatus

-- | Ntp client thread
[ntpThread] :: NtpClient -> Async Void

-- | The Ntp client state: either cached results is availbale, or the ntp
--   client is engaged in ntp-protocol or there was a failure: e.g.
--   connection lost, or dns lookups did not return at least
--   <a>ntpRequiredNumberOfResults</a> addresses.
data NtpStatus

-- | The difference between NTP time and local system time
NtpDrift :: !NtpOffset -> NtpStatus

-- | NTP client has send requests to the servers
NtpSyncPending :: NtpStatus

-- | NTP is not available: the client has not received any respond within
--   <a>ntpResponseTimeout</a> from at least
--   <a>ntpRequiredNumberOfResults</a> servers.
NtpSyncUnavailable :: NtpStatus

-- | Perform a series of NTP queries: one for each dns name. Resolve each
--   dns name, get local addresses: both IPv4 and IPv6 and engage in ntp
--   protocol towards one ip address per address family per dns name, but
--   only for address families for which we have a local address. This is
--   to avoid trying to send IPv4/6 requests if IPv4/6 gateway is not
--   configured.
--   
--   It may throw an <a>IOException</a>:
--   
--   <ul>
--   <li>if neither IPv4 nor IPv6 address is configured</li>
--   <li>if network I/O errors</li>
--   </ul>
ntpQuery :: IOManager -> Tracer IO NtpTrace -> NtpSettings -> IO NtpStatus
data NtpTrace
NtpTraceStartNtpClient :: NtpTrace
NtpTraceRestartDelay :: !Int -> NtpTrace
NtpTraceRestartingClient :: NtpTrace
NtpTraceIOError :: !IOError -> NtpTrace
NtpTraceLookupsFails :: NtpTrace
NtpTraceClientStartQuery :: NtpTrace
NtpTraceNoLocalAddr :: NtpTrace
NtpTraceResult :: !NtpStatus -> NtpTrace
NtpTraceRunProtocolResults :: !ResultOrFailure [NtpOffset] -> NtpTrace
NtpTracePacketSent :: !SockAddr -> !NtpPacket -> NtpTrace
NtpTracePacketSendError :: !SockAddr -> !IOException -> NtpTrace
NtpTracePacketDecodeError :: !SockAddr -> !String -> NtpTrace
NtpTracePacketReceived :: SockAddr -> !NtpPacket -> NtpTrace
NtpTraceWaitingForRepliesTimeout :: !IPVersion -> NtpTrace

-- | A tag which describes which version of the ip protocol was used.
data IPVersion
IPv4 :: IPVersion
IPv6 :: IPVersion

-- | Result of two threads running concurrently.
data ResultOrFailure a

-- | both threads suceeded
BothSucceeded :: !a -> ResultOrFailure a

-- | one of the threads errors. <a>IPVersion</a> indicates which one.
SuccessAndFailure :: !a -> !IPVersion -> !IOException -> ResultOrFailure a

-- | both threads failed
BothFailed :: !IOException -> !IOException -> ResultOrFailure a
