{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}

module Logging.Logs (Source (..), Severity (..), LogMessage (..), Scope) where

import qualified Data.Aeson as Aeson
import Data.Time (UTCTime)
import Data.UUID (UUID)

import Docs.UserRef (UserRef)

import Control.Lens ((&), (.~), (?~))
import Data.Aeson (FromJSON, ToJSON)
import qualified Data.HashMap.Strict.InsOrd as InsOrd
import Data.OpenApi
    ( HasAdditionalProperties (additionalProperties)
    , HasProperties (..)
    , NamedSchema (NamedSchema)
    , OpenApiType (OpenApiObject)
    , Referenced (Inline)
    , ToSchema
    , declareSchemaRef
    )
import qualified Data.OpenApi as OpenApi
import Data.OpenApi.Lens (HasType (..))
import Data.OpenApi.Schema (ToSchema (..))
import Data.Proxy (Proxy (Proxy))
import Data.Text (Text)
import GHC.Generics (Generic)
import Logging.Scope (Scope)

data Severity = Info | Warning | Error deriving ((forall x. Severity -> Rep Severity x)
-> (forall x. Rep Severity x -> Severity) -> Generic Severity
forall x. Rep Severity x -> Severity
forall x. Severity -> Rep Severity x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Severity -> Rep Severity x
from :: forall x. Severity -> Rep Severity x
$cto :: forall x. Rep Severity x -> Severity
to :: forall x. Rep Severity x -> Severity
Generic)

instance ToJSON Severity

instance FromJSON Severity

instance ToSchema Severity

data Source = User UserRef | System deriving ((forall x. Source -> Rep Source x)
-> (forall x. Rep Source x -> Source) -> Generic Source
forall x. Rep Source x -> Source
forall x. Source -> Rep Source x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Source -> Rep Source x
from :: forall x. Source -> Rep Source x
$cto :: forall x. Rep Source x -> Source
to :: forall x. Rep Source x -> Source
Generic)

instance ToJSON Source

instance FromJSON Source

instance ToSchema Source

data LogMessage = LogMessage
    { LogMessage -> UUID
identifier :: UUID
    , LogMessage -> Severity
severity :: Severity
    , LogMessage -> UTCTime
timestamp :: UTCTime
    , LogMessage -> Source
source :: Source
    , LogMessage -> Scope
scope :: Scope
    , LogMessage -> Value
content :: Aeson.Value
    }
    deriving ((forall x. LogMessage -> Rep LogMessage x)
-> (forall x. Rep LogMessage x -> LogMessage) -> Generic LogMessage
forall x. Rep LogMessage x -> LogMessage
forall x. LogMessage -> Rep LogMessage x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. LogMessage -> Rep LogMessage x
from :: forall x. LogMessage -> Rep LogMessage x
$cto :: forall x. Rep LogMessage x -> LogMessage
to :: forall x. Rep LogMessage x -> LogMessage
Generic)

instance ToJSON LogMessage

instance FromJSON LogMessage

instance ToSchema LogMessage where
    declareNamedSchema :: Proxy LogMessage -> Declare (Definitions Schema) NamedSchema
declareNamedSchema Proxy LogMessage
_ = do
        Referenced Schema
idSchema <- Proxy UUID -> Declare (Definitions Schema) (Referenced Schema)
forall a.
ToSchema a =>
Proxy a -> Declare (Definitions Schema) (Referenced Schema)
declareSchemaRef (Proxy UUID
forall {k} (t :: k). Proxy t
Proxy :: Proxy UUID)
        Referenced Schema
severitySchmema <- Proxy Severity -> Declare (Definitions Schema) (Referenced Schema)
forall a.
ToSchema a =>
Proxy a -> Declare (Definitions Schema) (Referenced Schema)
declareSchemaRef (Proxy Severity
forall {k} (t :: k). Proxy t
Proxy :: Proxy Severity)
        Referenced Schema
timestampSchema <- Proxy UTCTime -> Declare (Definitions Schema) (Referenced Schema)
forall a.
ToSchema a =>
Proxy a -> Declare (Definitions Schema) (Referenced Schema)
declareSchemaRef (Proxy UTCTime
forall {k} (t :: k). Proxy t
Proxy :: Proxy UTCTime)
        Referenced Schema
sourceSchema <- Proxy Source -> Declare (Definitions Schema) (Referenced Schema)
forall a.
ToSchema a =>
Proxy a -> Declare (Definitions Schema) (Referenced Schema)
declareSchemaRef (Proxy Source
forall {k} (t :: k). Proxy t
Proxy :: Proxy Source)
        Referenced Schema
scopeSchema <- Proxy Text -> Declare (Definitions Schema) (Referenced Schema)
forall a.
ToSchema a =>
Proxy a -> Declare (Definitions Schema) (Referenced Schema)
declareSchemaRef (Proxy Text
forall {k} (t :: k). Proxy t
Proxy :: Proxy Text)
        let contentSchema :: Schema
contentSchema =
                Schema
forall a. Monoid a => a
mempty
                    Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe OpenApiType -> Identity (Maybe OpenApiType))
-> Schema -> Identity Schema
forall s a. HasType s a => Lens' s a
Lens' Schema (Maybe OpenApiType)
type_ ((Maybe OpenApiType -> Identity (Maybe OpenApiType))
 -> Schema -> Identity Schema)
-> OpenApiType -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ OpenApiType
OpenApiObject
                    Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe AdditionalProperties
 -> Identity (Maybe AdditionalProperties))
-> Schema -> Identity Schema
forall s a. HasAdditionalProperties s a => Lens' s a
Lens' Schema (Maybe AdditionalProperties)
additionalProperties ((Maybe AdditionalProperties
  -> Identity (Maybe AdditionalProperties))
 -> Schema -> Identity Schema)
-> AdditionalProperties -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ Bool -> AdditionalProperties
OpenApi.AdditionalPropertiesAllowed Bool
True
        NamedSchema -> Declare (Definitions Schema) NamedSchema
forall a. a -> DeclareT (Definitions Schema) Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (NamedSchema -> Declare (Definitions Schema) NamedSchema)
-> NamedSchema -> Declare (Definitions Schema) NamedSchema
forall a b. (a -> b) -> a -> b
$
            Maybe Text -> Schema -> NamedSchema
NamedSchema (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"LogMessage") (Schema -> NamedSchema) -> Schema -> NamedSchema
forall a b. (a -> b) -> a -> b
$
                Schema
forall a. Monoid a => a
mempty
                    Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe OpenApiType -> Identity (Maybe OpenApiType))
-> Schema -> Identity Schema
forall s a. HasType s a => Lens' s a
Lens' Schema (Maybe OpenApiType)
type_
                        ((Maybe OpenApiType -> Identity (Maybe OpenApiType))
 -> Schema -> Identity Schema)
-> OpenApiType -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ OpenApiType
OpenApiObject
                    Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (InsOrdHashMap Text (Referenced Schema)
 -> Identity (InsOrdHashMap Text (Referenced Schema)))
-> Schema -> Identity Schema
forall s a. HasProperties s a => Lens' s a
Lens' Schema (InsOrdHashMap Text (Referenced Schema))
properties
                        ((InsOrdHashMap Text (Referenced Schema)
  -> Identity (InsOrdHashMap Text (Referenced Schema)))
 -> Schema -> Identity Schema)
-> InsOrdHashMap Text (Referenced Schema) -> Schema -> Schema
forall s t a b. ASetter s t a b -> b -> s -> t
.~ [(Text, Referenced Schema)]
-> InsOrdHashMap Text (Referenced Schema)
forall k v. (Eq k, Hashable k) => [(k, v)] -> InsOrdHashMap k v
InsOrd.fromList
                            [ (Text
"identifier", Referenced Schema
idSchema)
                            , (Text
"severity", Referenced Schema
severitySchmema)
                            , (Text
"timestamp", Referenced Schema
timestampSchema)
                            , (Text
"source", Referenced Schema
sourceSchema)
                            , (Text
"scope", Referenced Schema
scopeSchema)
                            , (Text
"content", Schema -> Referenced Schema
forall a. a -> Referenced a
Inline Schema
contentSchema)
                            ]