module Network.Bugsnag.Event
    ( BugsnagEvent(..)
    , bugsnagEvent
    ) where

import Prelude

import Data.Aeson
import Data.Aeson.Ext
import Data.Aeson.Types
import Data.Text (Text)
import Network.Bugsnag.App
import Network.Bugsnag.Breadcrumb
import Network.Bugsnag.Device
import Network.Bugsnag.Exception
import Network.Bugsnag.Request
import Network.Bugsnag.Severity
import Network.Bugsnag.Thread
import Network.Bugsnag.User

data BugsnagEvent = BugsnagEvent
    { BugsnagEvent -> BugsnagException
beException :: BugsnagException
    , BugsnagEvent -> Maybe [BugsnagBreadcrumb]
beBreadcrumbs :: Maybe [BugsnagBreadcrumb]
    , BugsnagEvent -> Maybe BugsnagRequest
beRequest :: Maybe BugsnagRequest
    , BugsnagEvent -> Maybe [BugsnagThread]
beThreads :: Maybe [BugsnagThread]
    , BugsnagEvent -> Maybe Text
beContext :: Maybe Text
    , BugsnagEvent -> Maybe Text
beGroupingHash :: Maybe Text
    , BugsnagEvent -> Maybe Bool
beUnhandled :: Maybe Bool
    , BugsnagEvent -> Maybe BugsnagSeverity
beSeverity :: Maybe BugsnagSeverity
    , BugsnagEvent -> Maybe BugsnagSeverityReason
beSeverityReason :: Maybe BugsnagSeverityReason
    , BugsnagEvent -> Maybe BugsnagUser
beUser :: Maybe BugsnagUser
    , BugsnagEvent -> Maybe BugsnagApp
beApp :: Maybe BugsnagApp
    , BugsnagEvent -> Maybe BugsnagDevice
beDevice :: Maybe BugsnagDevice
    --, beSession
    -- N.B. omitted because it's an object specific to the Session Tracking API,
    -- and I'm not sure yet how to resolve the naming clash with BugsnagSession.
    , BugsnagEvent -> Maybe Value
beMetaData :: Maybe Value
    }

instance ToJSON BugsnagEvent where
    -- | Explicit instance needed to send @'beException'@ as @exceptions@
    toJSON :: BugsnagEvent -> Value
toJSON BugsnagEvent {Maybe Bool
Maybe [BugsnagBreadcrumb]
Maybe [BugsnagThread]
Maybe Text
Maybe Value
Maybe BugsnagDevice
Maybe BugsnagApp
Maybe BugsnagRequest
Maybe BugsnagSeverityReason
Maybe BugsnagSeverity
Maybe BugsnagUser
BugsnagException
beMetaData :: Maybe Value
beDevice :: Maybe BugsnagDevice
beApp :: Maybe BugsnagApp
beUser :: Maybe BugsnagUser
beSeverityReason :: Maybe BugsnagSeverityReason
beSeverity :: Maybe BugsnagSeverity
beUnhandled :: Maybe Bool
beGroupingHash :: Maybe Text
beContext :: Maybe Text
beThreads :: Maybe [BugsnagThread]
beRequest :: Maybe BugsnagRequest
beBreadcrumbs :: Maybe [BugsnagBreadcrumb]
beException :: BugsnagException
beMetaData :: BugsnagEvent -> Maybe Value
beDevice :: BugsnagEvent -> Maybe BugsnagDevice
beApp :: BugsnagEvent -> Maybe BugsnagApp
beUser :: BugsnagEvent -> Maybe BugsnagUser
beSeverityReason :: BugsnagEvent -> Maybe BugsnagSeverityReason
beSeverity :: BugsnagEvent -> Maybe BugsnagSeverity
beUnhandled :: BugsnagEvent -> Maybe Bool
beGroupingHash :: BugsnagEvent -> Maybe Text
beContext :: BugsnagEvent -> Maybe Text
beThreads :: BugsnagEvent -> Maybe [BugsnagThread]
beRequest :: BugsnagEvent -> Maybe BugsnagRequest
beBreadcrumbs :: BugsnagEvent -> Maybe [BugsnagBreadcrumb]
beException :: BugsnagEvent -> BugsnagException
..} = [Pair] -> Value
object ([Pair] -> Value) -> [Pair] -> Value
forall a b. (a -> b) -> a -> b
$ Key
"exceptions" Key -> [BugsnagException] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= [BugsnagException
beException] Pair -> [Pair] -> [Pair]
forall a. a -> [a] -> [a]
: [[Pair]] -> [Pair]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
        [ Text
"breadcrumbs" Text -> Maybe [BugsnagBreadcrumb] -> [Pair]
forall v. ToJSON v => Text -> Maybe v -> [Pair]
.=? Maybe [BugsnagBreadcrumb]
beBreadcrumbs
        , Text
"request" Text -> Maybe BugsnagRequest -> [Pair]
forall v. ToJSON v => Text -> Maybe v -> [Pair]
.=? Maybe BugsnagRequest
beRequest
        , Text
"threads" Text -> Maybe [BugsnagThread] -> [Pair]
forall v. ToJSON v => Text -> Maybe v -> [Pair]
.=? Maybe [BugsnagThread]
beThreads
        , Text
"context" Text -> Maybe Text -> [Pair]
forall v. ToJSON v => Text -> Maybe v -> [Pair]
.=? Maybe Text
beContext
        , Text
"groupingHash" Text -> Maybe Text -> [Pair]
forall v. ToJSON v => Text -> Maybe v -> [Pair]
.=? Maybe Text
beGroupingHash
        , Text
"unhandled" Text -> Maybe Bool -> [Pair]
forall v. ToJSON v => Text -> Maybe v -> [Pair]
.=? Maybe Bool
beUnhandled
        , Text
"severity" Text -> Maybe BugsnagSeverity -> [Pair]
forall v. ToJSON v => Text -> Maybe v -> [Pair]
.=? Maybe BugsnagSeverity
beSeverity
        , Text
"severityReason" Text -> Maybe BugsnagSeverityReason -> [Pair]
forall v. ToJSON v => Text -> Maybe v -> [Pair]
.=? Maybe BugsnagSeverityReason
beSeverityReason
        , Text
"user" Text -> Maybe BugsnagUser -> [Pair]
forall v. ToJSON v => Text -> Maybe v -> [Pair]
.=? Maybe BugsnagUser
beUser
        , Text
"app" Text -> Maybe BugsnagApp -> [Pair]
forall v. ToJSON v => Text -> Maybe v -> [Pair]
.=? Maybe BugsnagApp
beApp
        , Text
"device" Text -> Maybe BugsnagDevice -> [Pair]
forall v. ToJSON v => Text -> Maybe v -> [Pair]
.=? Maybe BugsnagDevice
beDevice
        , Text
"metaData" Text -> Maybe Value -> [Pair]
forall v. ToJSON v => Text -> Maybe v -> [Pair]
.=? Maybe Value
beMetaData
        ]
      where
        -- For implementing "omit Nothing fields"
        (.=?) :: ToJSON v => Text -> Maybe v -> [Pair]
        .=? :: Text -> Maybe v -> [Pair]
(.=?) Text
k = [Pair] -> (v -> [Pair]) -> Maybe v -> [Pair]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (Pair -> [Pair]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Pair -> [Pair]) -> (v -> Pair) -> v -> [Pair]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Key
fromText Text
k Key -> v -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.=))

bugsnagEvent :: BugsnagException -> BugsnagEvent
bugsnagEvent :: BugsnagException -> BugsnagEvent
bugsnagEvent BugsnagException
exception = BugsnagEvent :: BugsnagException
-> Maybe [BugsnagBreadcrumb]
-> Maybe BugsnagRequest
-> Maybe [BugsnagThread]
-> Maybe Text
-> Maybe Text
-> Maybe Bool
-> Maybe BugsnagSeverity
-> Maybe BugsnagSeverityReason
-> Maybe BugsnagUser
-> Maybe BugsnagApp
-> Maybe BugsnagDevice
-> Maybe Value
-> BugsnagEvent
BugsnagEvent
    { beException :: BugsnagException
beException = BugsnagException
exception
    , beBreadcrumbs :: Maybe [BugsnagBreadcrumb]
beBreadcrumbs = Maybe [BugsnagBreadcrumb]
forall a. Maybe a
Nothing
    , beRequest :: Maybe BugsnagRequest
beRequest = Maybe BugsnagRequest
forall a. Maybe a
Nothing
    , beThreads :: Maybe [BugsnagThread]
beThreads = Maybe [BugsnagThread]
forall a. Maybe a
Nothing
    , beContext :: Maybe Text
beContext = Maybe Text
forall a. Maybe a
Nothing
    , beGroupingHash :: Maybe Text
beGroupingHash = Maybe Text
forall a. Maybe a
Nothing
    , beUnhandled :: Maybe Bool
beUnhandled = Maybe Bool
forall a. Maybe a
Nothing
    , beSeverity :: Maybe BugsnagSeverity
beSeverity = Maybe BugsnagSeverity
forall a. Maybe a
Nothing
    , beSeverityReason :: Maybe BugsnagSeverityReason
beSeverityReason = Maybe BugsnagSeverityReason
forall a. Maybe a
Nothing
    , beUser :: Maybe BugsnagUser
beUser = Maybe BugsnagUser
forall a. Maybe a
Nothing
    , beApp :: Maybe BugsnagApp
beApp = Maybe BugsnagApp
forall a. Maybe a
Nothing
    , beDevice :: Maybe BugsnagDevice
beDevice = Maybe BugsnagDevice
forall a. Maybe a
Nothing
    , beMetaData :: Maybe Value
beMetaData = Maybe Value
forall a. Maybe a
Nothing
    }