{-# LANGUAGE OverloadedStrings #-}

{-|
Events in Datadog represent notable occurrences.
-}
module Network.Datadog.Event
( EventPriority(..)
, AlertType(..)
, SourceType(..)
, EventSpec(..)
, Event(eventId', eventDetails)
, EventId
, minimalEventSpec
, createEvent
, loadEvent
, loadEvents
, AsEventPriority(..)
, AsAlertType(..)
, AsSourceType(..)
, HasTitle(..)
, HasText(..)
, HasPriority(..)
, HasDateHappened(..)
, HasAlertType(..)
, HasDetails(..)
, HasTags(..)
, HasSourceType(..)
, HasHost(..)
, HasId'(..)
) where


import Control.Monad (liftM)

import Data.Aeson hiding (Error, Success)
-- import qualified Data.Aeson (Result(Success))
import Data.List (intercalate)
import Data.Text (Text, unpack)
import Data.Time.Clock
import Data.Time.Clock.POSIX

import Network.HTTP.Types

import Network.Datadog.Internal

-- | Creates the most basic description required for an event, containing the
-- event title, descriptive text, time of occurrence, and priority of the
-- event. This event will be of type Info.
minimalEventSpec :: Text -> Text -> UTCTime -> EventPriority -> EventSpec
minimalEventSpec :: Text -> Text -> UTCTime -> EventPriority -> EventSpec
minimalEventSpec Text
specTitle Text
specText UTCTime
time EventPriority
eventPriority = EventSpec :: Text
-> Text
-> UTCTime
-> EventPriority
-> Maybe Text
-> [Tag]
-> AlertType
-> Maybe SourceType
-> EventSpec
EventSpec
  { eventSpecTitle :: Text
eventSpecTitle = Text
specTitle
  , eventSpecText :: Text
eventSpecText = Text
specText
  , eventSpecDateHappened :: UTCTime
eventSpecDateHappened = UTCTime
time
  , eventSpecPriority :: EventPriority
eventSpecPriority = EventPriority
eventPriority
  , eventSpecHost :: Maybe Text
eventSpecHost = Maybe Text
forall a. Maybe a
Nothing
  , eventSpecTags :: [Tag]
eventSpecTags = []
  , eventSpecAlertType :: AlertType
eventSpecAlertType = AlertType
Info
  , eventSpecSourceType :: Maybe SourceType
eventSpecSourceType = Maybe SourceType
forall a. Maybe a
Nothing
  }


-- | Store a new event in Datadog.
createEvent :: Environment -> EventSpec -> IO Event
createEvent :: Environment -> EventSpec -> IO Event
createEvent Environment
env EventSpec
eventSpec =
  let path :: p
path = p
"events"
  in (WrappedEvent -> Event) -> IO WrappedEvent -> IO Event
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM WrappedEvent -> Event
wrappedEvent (IO WrappedEvent -> IO Event) -> IO WrappedEvent -> IO Event
forall a b. (a -> b) -> a -> b
$
     Environment
-> String
-> [(String, String)]
-> StdMethod
-> Maybe ByteString
-> IO ByteString
datadogHttp Environment
env String
forall p. IsString p => p
path [] StdMethod
POST (ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (ByteString -> Maybe ByteString) -> ByteString -> Maybe ByteString
forall a b. (a -> b) -> a -> b
$ EventSpec -> ByteString
forall a. ToJSON a => a -> ByteString
encode EventSpec
eventSpec) IO ByteString -> (ByteString -> IO WrappedEvent) -> IO WrappedEvent
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
     String -> ByteString -> IO WrappedEvent
forall a. FromJSON a => String -> ByteString -> IO a
decodeDatadog String
"createEvent"


-- | Load an event from Datadog by its ID.
loadEvent :: Environment -> EventId -> IO Event
loadEvent :: Environment -> EventId -> IO Event
loadEvent Environment
env EventId
eventId =
  let path :: String
path = String
"events/" String -> String -> String
forall a. [a] -> [a] -> [a]
++ EventId -> String
forall a. Show a => a -> String
show EventId
eventId
  in (WrappedEvent -> Event) -> IO WrappedEvent -> IO Event
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM WrappedEvent -> Event
wrappedEvent (IO WrappedEvent -> IO Event) -> IO WrappedEvent -> IO Event
forall a b. (a -> b) -> a -> b
$
     Environment
-> String
-> [(String, String)]
-> StdMethod
-> Maybe ByteString
-> IO ByteString
datadogHttp Environment
env String
path [] StdMethod
GET Maybe ByteString
forall a. Maybe a
Nothing IO ByteString -> (ByteString -> IO WrappedEvent) -> IO WrappedEvent
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
     String -> ByteString -> IO WrappedEvent
forall a. FromJSON a => String -> ByteString -> IO a
decodeDatadog String
"loadEvent"

-- | Query Datadog for events within a specific time range.
loadEvents :: Environment
           -> (UTCTime,UTCTime)
           -- ^ The range within which to query for events
           -> Maybe EventPriority
           -- ^ Optionally filter results by a specific priority level
           -> [Text]
           -- ^ A list of tags to filter by
           -> IO [Event]
loadEvents :: Environment
-> (UTCTime, UTCTime)
-> Maybe EventPriority
-> [Text]
-> IO [Event]
loadEvents Environment
env (UTCTime
startTime, UTCTime
endTime) Maybe EventPriority
resultPriority [Text]
filterTags =
  let path :: p
path = p
"events"
      q :: [(String, String)]
q = (EventPriority -> (String, String))
-> Maybe EventPriority -> [(String, String)] -> [(String, String)]
forall a b. (a -> b) -> Maybe a -> [b] -> [b]
prependMaybe (\EventPriority
a -> (String
"priority", EventPriority -> String
forall a. Show a => a -> String
show EventPriority
a)) Maybe EventPriority
resultPriority ([(String, String)] -> [(String, String)])
-> [(String, String)] -> [(String, String)]
forall a b. (a -> b) -> a -> b
$
            Bool
-> (String, String) -> [(String, String)] -> [(String, String)]
forall b. Bool -> b -> [b] -> [b]
prependBool (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [Text] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Text]
filterTags) (String
"tags", String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"," ((Text -> String) -> [Text] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Text -> String
unpack [Text]
filterTags))
            [(String
"start", Integer -> String
forall a. Show a => a -> String
show (POSIXTime -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
floor (UTCTime -> POSIXTime
utcTimeToPOSIXSeconds UTCTime
startTime) :: Integer))
            ,(String
"end", Integer -> String
forall a. Show a => a -> String
show (POSIXTime -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
floor (UTCTime -> POSIXTime
utcTimeToPOSIXSeconds UTCTime
endTime) :: Integer))
            ]
  in (WrappedEvents -> [Event]) -> IO WrappedEvents -> IO [Event]
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM WrappedEvents -> [Event]
wrappedEvents (IO WrappedEvents -> IO [Event]) -> IO WrappedEvents -> IO [Event]
forall a b. (a -> b) -> a -> b
$
     Environment
-> String
-> [(String, String)]
-> StdMethod
-> Maybe ByteString
-> IO ByteString
datadogHttp Environment
env String
forall p. IsString p => p
path [(String, String)]
q StdMethod
GET Maybe ByteString
forall a. Maybe a
Nothing IO ByteString
-> (ByteString -> IO WrappedEvents) -> IO WrappedEvents
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
     String -> ByteString -> IO WrappedEvents
forall a. FromJSON a => String -> ByteString -> IO a
decodeDatadog String
"loadEvent"