{-# LANGUAGE StrictData #-}
{-# LANGUAGE TemplateHaskell #-}

-- This file is part of the Wire Server implementation.
--
-- Copyright (C) 2022 Wire Swiss GmbH <opensource@wire.com>
--
-- This program is free software: you can redistribute it and/or modify it under
-- the terms of the GNU Affero General Public License as published by the Free
-- Software Foundation, either version 3 of the License, or (at your option) any
-- later version.
--
-- This program is distributed in the hope that it will be useful, but WITHOUT
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-- FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
-- details.
--
-- You should have received a copy of the GNU Affero General Public License along
-- with this program. If not, see <https://www.gnu.org/licenses/>.

module Wire.API.Notification
  ( NotificationId,
    isValidNotificationId,
    RawNotificationId (..),
    Event,

    -- * QueuedNotification
    QueuedNotification,
    queuedNotification,
    queuedNotificationId,
    queuedNotificationPayload,
    QueuedNotificationList,
    queuedNotificationList,
    queuedNotifications,
    queuedHasMore,
    queuedTime,
    GetNotificationsResponse (..),
  )
where

import Control.Lens (makeLenses, (.~))
import Control.Lens.Operators ((?~))
import Data.Aeson (FromJSON (..), ToJSON (..))
import Data.Aeson.Types qualified as Aeson
import Data.Bits
import Data.HashMap.Strict.InsOrd qualified as InsOrdHashMap
import Data.Id
import Data.Json.Util
import Data.List.NonEmpty (NonEmpty)
import Data.OpenApi (ToParamSchema (..))
import Data.OpenApi qualified as S
import Data.SOP
import Data.Schema
import Data.Text.Encoding
import Data.Time.Clock (UTCTime)
import Data.UUID qualified as UUID
import Imports
import Servant
import Wire.API.Routes.MultiVerb
import Wire.Arbitrary (Arbitrary, GenericUniform (..))

type NotificationId = Id QueuedNotification

-- FUTUREWORK:
-- This definition is very opaque, but we know some of the structure already
-- (e.g. visible in 'modelEvent'). Can we specify it in a better way?
type Event = Aeson.Object

-- | Schema for an `Event` object.
--
-- This is basically a schema for a JSON object with some pre-defined structure.
eventSchema :: ValueSchema NamedSwaggerDoc Event
eventSchema :: ValueSchema NamedSwaggerDoc Object
eventSchema = NamedSwaggerDoc
-> (Value -> Parser Object)
-> (Object -> Maybe Value)
-> ValueSchema NamedSwaggerDoc Object
forall doc v b a w.
doc -> (v -> Parser b) -> (a -> Maybe w) -> SchemaP doc v w a b
mkSchema NamedSwaggerDoc
sdoc Value -> Parser Object
forall a. FromJSON a => Value -> Parser a
Aeson.parseJSON (Value -> Maybe Value
forall a. a -> Maybe a
Just (Value -> Maybe Value)
-> (Object -> Value) -> Object -> Maybe Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Object -> Value
forall a. ToJSON a => a -> Value
Aeson.toJSON)
  where
    sdoc :: NamedSwaggerDoc
    sdoc :: NamedSwaggerDoc
sdoc =
      forall a. ToSchema a => NamedSwaggerDoc
swaggerDoc @Aeson.Object
        NamedSwaggerDoc
-> (NamedSwaggerDoc -> NamedSwaggerDoc) -> NamedSwaggerDoc
forall a b. a -> (a -> b) -> b
& (Schema -> Identity Schema)
-> NamedSwaggerDoc -> Identity NamedSwaggerDoc
forall s a. HasSchema s a => Lens' s a
Lens' NamedSwaggerDoc Schema
S.schema ((Schema -> Identity Schema)
 -> NamedSwaggerDoc -> Identity NamedSwaggerDoc)
-> ((Maybe Text -> Identity (Maybe Text))
    -> Schema -> Identity Schema)
-> (Maybe Text -> Identity (Maybe Text))
-> NamedSwaggerDoc
-> Identity NamedSwaggerDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe Text -> Identity (Maybe Text)) -> Schema -> Identity Schema
forall s a. HasTitle s a => Lens' s a
Lens' Schema (Maybe Text)
S.title ((Maybe Text -> Identity (Maybe Text))
 -> NamedSwaggerDoc -> Identity NamedSwaggerDoc)
-> Text -> NamedSwaggerDoc -> NamedSwaggerDoc
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ Text
"Event"
        NamedSwaggerDoc
-> (NamedSwaggerDoc -> NamedSwaggerDoc) -> NamedSwaggerDoc
forall a b. a -> (a -> b) -> b
& (Schema -> Identity Schema)
-> NamedSwaggerDoc -> Identity NamedSwaggerDoc
forall s a. HasSchema s a => Lens' s a
Lens' NamedSwaggerDoc Schema
S.schema ((Schema -> Identity Schema)
 -> NamedSwaggerDoc -> Identity NamedSwaggerDoc)
-> ((Maybe Text -> Identity (Maybe Text))
    -> Schema -> Identity Schema)
-> (Maybe Text -> Identity (Maybe Text))
-> NamedSwaggerDoc
-> Identity NamedSwaggerDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe Text -> Identity (Maybe Text)) -> Schema -> Identity Schema
forall s a. HasDescription s a => Lens' s a
Lens' Schema (Maybe Text)
S.description ((Maybe Text -> Identity (Maybe Text))
 -> NamedSwaggerDoc -> Identity NamedSwaggerDoc)
-> Text -> NamedSwaggerDoc -> NamedSwaggerDoc
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ Text
"A single notification event"
        NamedSwaggerDoc
-> (NamedSwaggerDoc -> NamedSwaggerDoc) -> NamedSwaggerDoc
forall a b. a -> (a -> b) -> b
& (Schema -> Identity Schema)
-> NamedSwaggerDoc -> Identity NamedSwaggerDoc
forall s a. HasSchema s a => Lens' s a
Lens' NamedSwaggerDoc Schema
S.schema ((Schema -> Identity Schema)
 -> NamedSwaggerDoc -> Identity NamedSwaggerDoc)
-> ((InsOrdHashMap Text (Referenced Schema)
     -> Identity (InsOrdHashMap Text (Referenced Schema)))
    -> Schema -> Identity Schema)
-> (InsOrdHashMap Text (Referenced Schema)
    -> Identity (InsOrdHashMap Text (Referenced Schema)))
-> NamedSwaggerDoc
-> Identity NamedSwaggerDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (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))
S.properties
          ((InsOrdHashMap Text (Referenced Schema)
  -> Identity (InsOrdHashMap Text (Referenced Schema)))
 -> NamedSwaggerDoc -> Identity NamedSwaggerDoc)
-> InsOrdHashMap Text (Referenced Schema)
-> NamedSwaggerDoc
-> NamedSwaggerDoc
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
InsOrdHashMap.fromList
            [ ( Text
"type",
                Schema -> Referenced Schema
forall a. a -> Referenced a
S.Inline (Proxy Text -> Schema
forall a. ToSchema a => Proxy a -> Schema
S.toSchema (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Text) Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe Text -> Identity (Maybe Text)) -> Schema -> Identity Schema
forall s a. HasDescription s a => Lens' s a
Lens' Schema (Maybe Text)
S.description ((Maybe Text -> Identity (Maybe Text))
 -> Schema -> Identity Schema)
-> Text -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ Text
"Event type")
              )
            ]

isValidNotificationId :: NotificationId -> Bool
isValidNotificationId :: NotificationId -> Bool
isValidNotificationId (Id UUID
uuid) =
  -- check that the version bits are set to 1
  case UUID -> (Word32, Word32, Word32, Word32)
UUID.toWords UUID
uuid of
    (Word32
_, Word32
w, Word32
_, Word32
_) -> (Word32
w Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftR` Int
12) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32
0xf Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
== Word32
1

--------------------------------------------------------------------------------
-- QueuedNotification

data QueuedNotification = QueuedNotification
  { QueuedNotification -> NotificationId
_queuedNotificationId :: NotificationId,
    QueuedNotification -> NonEmpty Object
_queuedNotificationPayload :: NonEmpty Event
  }
  deriving stock (QueuedNotification -> QueuedNotification -> Bool
(QueuedNotification -> QueuedNotification -> Bool)
-> (QueuedNotification -> QueuedNotification -> Bool)
-> Eq QueuedNotification
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: QueuedNotification -> QueuedNotification -> Bool
== :: QueuedNotification -> QueuedNotification -> Bool
$c/= :: QueuedNotification -> QueuedNotification -> Bool
/= :: QueuedNotification -> QueuedNotification -> Bool
Eq, Int -> QueuedNotification -> ShowS
[QueuedNotification] -> ShowS
QueuedNotification -> String
(Int -> QueuedNotification -> ShowS)
-> (QueuedNotification -> String)
-> ([QueuedNotification] -> ShowS)
-> Show QueuedNotification
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> QueuedNotification -> ShowS
showsPrec :: Int -> QueuedNotification -> ShowS
$cshow :: QueuedNotification -> String
show :: QueuedNotification -> String
$cshowList :: [QueuedNotification] -> ShowS
showList :: [QueuedNotification] -> ShowS
Show, (forall x. QueuedNotification -> Rep QueuedNotification x)
-> (forall x. Rep QueuedNotification x -> QueuedNotification)
-> Generic QueuedNotification
forall x. Rep QueuedNotification x -> QueuedNotification
forall x. QueuedNotification -> Rep QueuedNotification x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. QueuedNotification -> Rep QueuedNotification x
from :: forall x. QueuedNotification -> Rep QueuedNotification x
$cto :: forall x. Rep QueuedNotification x -> QueuedNotification
to :: forall x. Rep QueuedNotification x -> QueuedNotification
Generic)
  deriving (Gen QueuedNotification
Gen QueuedNotification
-> (QueuedNotification -> [QueuedNotification])
-> Arbitrary QueuedNotification
QueuedNotification -> [QueuedNotification]
forall a. Gen a -> (a -> [a]) -> Arbitrary a
$carbitrary :: Gen QueuedNotification
arbitrary :: Gen QueuedNotification
$cshrink :: QueuedNotification -> [QueuedNotification]
shrink :: QueuedNotification -> [QueuedNotification]
Arbitrary) via (GenericUniform QueuedNotification)
  deriving ([QueuedNotification] -> Value
[QueuedNotification] -> Encoding
QueuedNotification -> Value
QueuedNotification -> Encoding
(QueuedNotification -> Value)
-> (QueuedNotification -> Encoding)
-> ([QueuedNotification] -> Value)
-> ([QueuedNotification] -> Encoding)
-> ToJSON QueuedNotification
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
$ctoJSON :: QueuedNotification -> Value
toJSON :: QueuedNotification -> Value
$ctoEncoding :: QueuedNotification -> Encoding
toEncoding :: QueuedNotification -> Encoding
$ctoJSONList :: [QueuedNotification] -> Value
toJSONList :: [QueuedNotification] -> Value
$ctoEncodingList :: [QueuedNotification] -> Encoding
toEncodingList :: [QueuedNotification] -> Encoding
ToJSON, Value -> Parser [QueuedNotification]
Value -> Parser QueuedNotification
(Value -> Parser QueuedNotification)
-> (Value -> Parser [QueuedNotification])
-> FromJSON QueuedNotification
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
$cparseJSON :: Value -> Parser QueuedNotification
parseJSON :: Value -> Parser QueuedNotification
$cparseJSONList :: Value -> Parser [QueuedNotification]
parseJSONList :: Value -> Parser [QueuedNotification]
FromJSON, Typeable QueuedNotification
Typeable QueuedNotification =>
(Proxy QueuedNotification
 -> Declare (Definitions Schema) NamedSchema)
-> ToSchema QueuedNotification
Proxy QueuedNotification
-> Declare (Definitions Schema) NamedSchema
forall a.
Typeable a =>
(Proxy a -> Declare (Definitions Schema) NamedSchema) -> ToSchema a
$cdeclareNamedSchema :: Proxy QueuedNotification
-> Declare (Definitions Schema) NamedSchema
declareNamedSchema :: Proxy QueuedNotification
-> Declare (Definitions Schema) NamedSchema
S.ToSchema) via (Schema QueuedNotification)

queuedNotification :: NotificationId -> NonEmpty Event -> QueuedNotification
queuedNotification :: NotificationId -> NonEmpty Object -> QueuedNotification
queuedNotification = NotificationId -> NonEmpty Object -> QueuedNotification
QueuedNotification

instance ToSchema QueuedNotification where
  schema :: ValueSchema NamedSwaggerDoc QueuedNotification
schema =
    Text
-> (NamedSwaggerDoc -> NamedSwaggerDoc)
-> ObjectSchema SwaggerDoc QueuedNotification
-> ValueSchema NamedSwaggerDoc QueuedNotification
forall doc doc' a.
HasObject doc doc' =>
Text -> (doc' -> doc') -> ObjectSchema doc a -> ValueSchema doc' a
objectWithDocModifier Text
"QueuedNotification" NamedSwaggerDoc -> NamedSwaggerDoc
queuedNotificationDoc (ObjectSchema SwaggerDoc QueuedNotification
 -> ValueSchema NamedSwaggerDoc QueuedNotification)
-> ObjectSchema SwaggerDoc QueuedNotification
-> ValueSchema NamedSwaggerDoc QueuedNotification
forall a b. (a -> b) -> a -> b
$
      NotificationId -> NonEmpty Object -> QueuedNotification
QueuedNotification
        (NotificationId -> NonEmpty Object -> QueuedNotification)
-> SchemaP
     SwaggerDoc Object [Pair] QueuedNotification NotificationId
-> SchemaP
     SwaggerDoc
     Object
     [Pair]
     QueuedNotification
     (NonEmpty Object -> QueuedNotification)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> QueuedNotification -> NotificationId
_queuedNotificationId
          (QueuedNotification -> NotificationId)
-> SchemaP SwaggerDoc Object [Pair] NotificationId NotificationId
-> SchemaP
     SwaggerDoc Object [Pair] QueuedNotification NotificationId
forall (p :: * -> * -> *) a a' b.
Profunctor p =>
(a -> a') -> p a' b -> p a b
.= Text
-> SchemaP
     NamedSwaggerDoc Value Value NotificationId NotificationId
-> SchemaP SwaggerDoc Object [Pair] NotificationId NotificationId
forall doc' doc a b.
HasField doc' doc =>
Text
-> SchemaP doc' Value Value a b -> SchemaP doc Object [Pair] a b
field Text
"id" SchemaP NamedSwaggerDoc Value Value NotificationId NotificationId
forall a. ToSchema a => ValueSchema NamedSwaggerDoc a
schema
        SchemaP
  SwaggerDoc
  Object
  [Pair]
  QueuedNotification
  (NonEmpty Object -> QueuedNotification)
-> SchemaP
     SwaggerDoc Object [Pair] QueuedNotification (NonEmpty Object)
-> ObjectSchema SwaggerDoc QueuedNotification
forall a b.
SchemaP SwaggerDoc Object [Pair] QueuedNotification (a -> b)
-> SchemaP SwaggerDoc Object [Pair] QueuedNotification a
-> SchemaP SwaggerDoc Object [Pair] QueuedNotification b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> QueuedNotification -> NonEmpty Object
_queuedNotificationPayload
          (QueuedNotification -> NonEmpty Object)
-> SchemaP
     SwaggerDoc Object [Pair] (NonEmpty Object) (NonEmpty Object)
-> SchemaP
     SwaggerDoc Object [Pair] QueuedNotification (NonEmpty Object)
forall (p :: * -> * -> *) a a' b.
Profunctor p =>
(a -> a') -> p a' b -> p a b
.= Text
-> (SwaggerDoc -> SwaggerDoc)
-> SchemaP
     SwaggerDoc Value Value (NonEmpty Object) (NonEmpty Object)
-> SchemaP
     SwaggerDoc Object [Pair] (NonEmpty Object) (NonEmpty Object)
forall doc' doc a b.
HasField doc' doc =>
Text
-> (doc' -> doc')
-> SchemaP doc' Value Value a b
-> SchemaP doc Object [Pair] a b
fieldWithDocModifier Text
"payload" SwaggerDoc -> SwaggerDoc
forall {b} {b}. (HasDescription b (Maybe b), IsString b) => b -> b
payloadDoc (ValueSchema NamedSwaggerDoc Object
-> SchemaP
     SwaggerDoc Value Value (NonEmpty Object) (NonEmpty Object)
forall ndoc doc a.
(HasArray ndoc doc, HasName ndoc,
 HasMinItems doc (Maybe Integer)) =>
ValueSchema ndoc a -> ValueSchema doc (NonEmpty a)
nonEmptyArray ValueSchema NamedSwaggerDoc Object
eventSchema)
    where
      queuedNotificationDoc :: NamedSwaggerDoc -> NamedSwaggerDoc
queuedNotificationDoc = (Maybe Text -> Identity (Maybe Text))
-> NamedSwaggerDoc -> Identity NamedSwaggerDoc
forall s a. HasDescription s a => Lens' s a
Lens' NamedSwaggerDoc (Maybe Text)
description ((Maybe Text -> Identity (Maybe Text))
 -> NamedSwaggerDoc -> Identity NamedSwaggerDoc)
-> Text -> NamedSwaggerDoc -> NamedSwaggerDoc
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ Text
"A single notification"
      payloadDoc :: b -> b
payloadDoc b
d = b
d b -> (b -> b) -> b
forall a b. a -> (a -> b) -> b
& (Maybe b -> Identity (Maybe b)) -> b -> Identity b
forall s a. HasDescription s a => Lens' s a
Lens' b (Maybe b)
description ((Maybe b -> Identity (Maybe b)) -> b -> Identity b) -> b -> b -> b
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ b
"List of events"

makeLenses ''QueuedNotification

data QueuedNotificationList = QueuedNotificationList
  { QueuedNotificationList -> [QueuedNotification]
_queuedNotifications :: [QueuedNotification],
    QueuedNotificationList -> Bool
_queuedHasMore :: Bool,
    QueuedNotificationList -> Maybe UTCTime
_queuedTime :: Maybe UTCTime
  }
  deriving stock (QueuedNotificationList -> QueuedNotificationList -> Bool
(QueuedNotificationList -> QueuedNotificationList -> Bool)
-> (QueuedNotificationList -> QueuedNotificationList -> Bool)
-> Eq QueuedNotificationList
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: QueuedNotificationList -> QueuedNotificationList -> Bool
== :: QueuedNotificationList -> QueuedNotificationList -> Bool
$c/= :: QueuedNotificationList -> QueuedNotificationList -> Bool
/= :: QueuedNotificationList -> QueuedNotificationList -> Bool
Eq, Int -> QueuedNotificationList -> ShowS
[QueuedNotificationList] -> ShowS
QueuedNotificationList -> String
(Int -> QueuedNotificationList -> ShowS)
-> (QueuedNotificationList -> String)
-> ([QueuedNotificationList] -> ShowS)
-> Show QueuedNotificationList
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> QueuedNotificationList -> ShowS
showsPrec :: Int -> QueuedNotificationList -> ShowS
$cshow :: QueuedNotificationList -> String
show :: QueuedNotificationList -> String
$cshowList :: [QueuedNotificationList] -> ShowS
showList :: [QueuedNotificationList] -> ShowS
Show, (forall x. QueuedNotificationList -> Rep QueuedNotificationList x)
-> (forall x.
    Rep QueuedNotificationList x -> QueuedNotificationList)
-> Generic QueuedNotificationList
forall x. Rep QueuedNotificationList x -> QueuedNotificationList
forall x. QueuedNotificationList -> Rep QueuedNotificationList x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. QueuedNotificationList -> Rep QueuedNotificationList x
from :: forall x. QueuedNotificationList -> Rep QueuedNotificationList x
$cto :: forall x. Rep QueuedNotificationList x -> QueuedNotificationList
to :: forall x. Rep QueuedNotificationList x -> QueuedNotificationList
Generic)
  deriving (Gen QueuedNotificationList
Gen QueuedNotificationList
-> (QueuedNotificationList -> [QueuedNotificationList])
-> Arbitrary QueuedNotificationList
QueuedNotificationList -> [QueuedNotificationList]
forall a. Gen a -> (a -> [a]) -> Arbitrary a
$carbitrary :: Gen QueuedNotificationList
arbitrary :: Gen QueuedNotificationList
$cshrink :: QueuedNotificationList -> [QueuedNotificationList]
shrink :: QueuedNotificationList -> [QueuedNotificationList]
Arbitrary) via (GenericUniform QueuedNotificationList)
  deriving ([QueuedNotificationList] -> Value
[QueuedNotificationList] -> Encoding
QueuedNotificationList -> Value
QueuedNotificationList -> Encoding
(QueuedNotificationList -> Value)
-> (QueuedNotificationList -> Encoding)
-> ([QueuedNotificationList] -> Value)
-> ([QueuedNotificationList] -> Encoding)
-> ToJSON QueuedNotificationList
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
$ctoJSON :: QueuedNotificationList -> Value
toJSON :: QueuedNotificationList -> Value
$ctoEncoding :: QueuedNotificationList -> Encoding
toEncoding :: QueuedNotificationList -> Encoding
$ctoJSONList :: [QueuedNotificationList] -> Value
toJSONList :: [QueuedNotificationList] -> Value
$ctoEncodingList :: [QueuedNotificationList] -> Encoding
toEncodingList :: [QueuedNotificationList] -> Encoding
ToJSON, Value -> Parser [QueuedNotificationList]
Value -> Parser QueuedNotificationList
(Value -> Parser QueuedNotificationList)
-> (Value -> Parser [QueuedNotificationList])
-> FromJSON QueuedNotificationList
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
$cparseJSON :: Value -> Parser QueuedNotificationList
parseJSON :: Value -> Parser QueuedNotificationList
$cparseJSONList :: Value -> Parser [QueuedNotificationList]
parseJSONList :: Value -> Parser [QueuedNotificationList]
FromJSON, Typeable QueuedNotificationList
Typeable QueuedNotificationList =>
(Proxy QueuedNotificationList
 -> Declare (Definitions Schema) NamedSchema)
-> ToSchema QueuedNotificationList
Proxy QueuedNotificationList
-> Declare (Definitions Schema) NamedSchema
forall a.
Typeable a =>
(Proxy a -> Declare (Definitions Schema) NamedSchema) -> ToSchema a
$cdeclareNamedSchema :: Proxy QueuedNotificationList
-> Declare (Definitions Schema) NamedSchema
declareNamedSchema :: Proxy QueuedNotificationList
-> Declare (Definitions Schema) NamedSchema
S.ToSchema) via (Schema QueuedNotificationList)

queuedNotificationList :: [QueuedNotification] -> Bool -> Maybe UTCTime -> QueuedNotificationList
queuedNotificationList :: [QueuedNotification]
-> Bool -> Maybe UTCTime -> QueuedNotificationList
queuedNotificationList = [QueuedNotification]
-> Bool -> Maybe UTCTime -> QueuedNotificationList
QueuedNotificationList

instance ToSchema QueuedNotificationList where
  schema :: ValueSchema NamedSwaggerDoc QueuedNotificationList
schema =
    Text
-> (NamedSwaggerDoc -> NamedSwaggerDoc)
-> ObjectSchema SwaggerDoc QueuedNotificationList
-> ValueSchema NamedSwaggerDoc QueuedNotificationList
forall doc doc' a.
HasObject doc doc' =>
Text -> (doc' -> doc') -> ObjectSchema doc a -> ValueSchema doc' a
objectWithDocModifier Text
"QueuedNotificationList" NamedSwaggerDoc -> NamedSwaggerDoc
queuedNotificationListDoc (ObjectSchema SwaggerDoc QueuedNotificationList
 -> ValueSchema NamedSwaggerDoc QueuedNotificationList)
-> ObjectSchema SwaggerDoc QueuedNotificationList
-> ValueSchema NamedSwaggerDoc QueuedNotificationList
forall a b. (a -> b) -> a -> b
$
      [QueuedNotification]
-> Bool -> Maybe UTCTime -> QueuedNotificationList
QueuedNotificationList
        ([QueuedNotification]
 -> Bool -> Maybe UTCTime -> QueuedNotificationList)
-> SchemaP
     SwaggerDoc
     Object
     [Pair]
     QueuedNotificationList
     [QueuedNotification]
-> SchemaP
     SwaggerDoc
     Object
     [Pair]
     QueuedNotificationList
     (Bool -> Maybe UTCTime -> QueuedNotificationList)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> QueuedNotificationList -> [QueuedNotification]
_queuedNotifications
          (QueuedNotificationList -> [QueuedNotification])
-> SchemaP
     SwaggerDoc Object [Pair] [QueuedNotification] [QueuedNotification]
-> SchemaP
     SwaggerDoc
     Object
     [Pair]
     QueuedNotificationList
     [QueuedNotification]
forall (p :: * -> * -> *) a a' b.
Profunctor p =>
(a -> a') -> p a' b -> p a b
.= Text
-> (SwaggerDoc -> SwaggerDoc)
-> SchemaP
     SwaggerDoc Value Value [QueuedNotification] [QueuedNotification]
-> SchemaP
     SwaggerDoc Object [Pair] [QueuedNotification] [QueuedNotification]
forall doc' doc a b.
HasField doc' doc =>
Text
-> (doc' -> doc')
-> SchemaP doc' Value Value a b
-> SchemaP doc Object [Pair] a b
fieldWithDocModifier Text
"notifications" SwaggerDoc -> SwaggerDoc
notificationsDoc (ValueSchema NamedSwaggerDoc QueuedNotification
-> SchemaP
     SwaggerDoc Value Value [QueuedNotification] [QueuedNotification]
forall ndoc doc a.
(HasArray ndoc doc, HasName ndoc) =>
ValueSchema ndoc a -> ValueSchema doc [a]
array ValueSchema NamedSwaggerDoc QueuedNotification
forall a. ToSchema a => ValueSchema NamedSwaggerDoc a
schema)
        SchemaP
  SwaggerDoc
  Object
  [Pair]
  QueuedNotificationList
  (Bool -> Maybe UTCTime -> QueuedNotificationList)
-> SchemaP SwaggerDoc Object [Pair] QueuedNotificationList Bool
-> SchemaP
     SwaggerDoc
     Object
     [Pair]
     QueuedNotificationList
     (Maybe UTCTime -> QueuedNotificationList)
forall a b.
SchemaP SwaggerDoc Object [Pair] QueuedNotificationList (a -> b)
-> SchemaP SwaggerDoc Object [Pair] QueuedNotificationList a
-> SchemaP SwaggerDoc Object [Pair] QueuedNotificationList b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> QueuedNotificationList -> Bool
_queuedHasMore
          (QueuedNotificationList -> Bool)
-> SchemaP SwaggerDoc Object [Pair] Bool Bool
-> SchemaP SwaggerDoc Object [Pair] QueuedNotificationList Bool
forall (p :: * -> * -> *) a a' b.
Profunctor p =>
(a -> a') -> p a' b -> p a b
.= (Maybe Bool -> Bool)
-> SchemaP SwaggerDoc Object [Pair] Bool (Maybe Bool)
-> SchemaP SwaggerDoc Object [Pair] Bool Bool
forall a b.
(a -> b)
-> SchemaP SwaggerDoc Object [Pair] Bool a
-> SchemaP SwaggerDoc Object [Pair] Bool b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Bool -> Maybe Bool -> Bool
forall a. a -> Maybe a -> a
fromMaybe Bool
False) (Text
-> (NamedSwaggerDoc -> NamedSwaggerDoc)
-> SchemaP NamedSwaggerDoc Value Value Bool Bool
-> SchemaP SwaggerDoc Object [Pair] Bool (Maybe Bool)
forall doc doc' a b.
(HasOpt doc, HasField doc' doc) =>
Text
-> (doc' -> doc')
-> SchemaP doc' Value Value a b
-> SchemaP doc Object [Pair] a (Maybe b)
optFieldWithDocModifier Text
"has_more" NamedSwaggerDoc -> NamedSwaggerDoc
hasMoreDoc SchemaP NamedSwaggerDoc Value Value Bool Bool
forall a. ToSchema a => ValueSchema NamedSwaggerDoc a
schema)
        SchemaP
  SwaggerDoc
  Object
  [Pair]
  QueuedNotificationList
  (Maybe UTCTime -> QueuedNotificationList)
-> SchemaP
     SwaggerDoc Object [Pair] QueuedNotificationList (Maybe UTCTime)
-> ObjectSchema SwaggerDoc QueuedNotificationList
forall a b.
SchemaP SwaggerDoc Object [Pair] QueuedNotificationList (a -> b)
-> SchemaP SwaggerDoc Object [Pair] QueuedNotificationList a
-> SchemaP SwaggerDoc Object [Pair] QueuedNotificationList b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> QueuedNotificationList -> Maybe UTCTime
_queuedTime
          (QueuedNotificationList -> Maybe UTCTime)
-> SchemaP SwaggerDoc Object [Pair] (Maybe UTCTime) (Maybe UTCTime)
-> SchemaP
     SwaggerDoc Object [Pair] QueuedNotificationList (Maybe UTCTime)
forall (p :: * -> * -> *) a a' b.
Profunctor p =>
(a -> a') -> p a' b -> p a b
.= SchemaP SwaggerDoc Object [Pair] UTCTime (Maybe UTCTime)
-> SchemaP SwaggerDoc Object [Pair] (Maybe UTCTime) (Maybe UTCTime)
forall w d v a b.
Monoid w =>
SchemaP d v w a b -> SchemaP d v w (Maybe a) b
maybe_ (Text
-> SchemaP NamedSwaggerDoc Value Value UTCTime UTCTime
-> SchemaP SwaggerDoc Object [Pair] UTCTime (Maybe UTCTime)
forall doc doc' a b.
(HasOpt doc, HasField doc' doc) =>
Text
-> SchemaP doc' Value Value a b
-> SchemaP doc Object [Pair] a (Maybe b)
optField Text
"time" SchemaP NamedSwaggerDoc Value Value UTCTime UTCTime
utcTimeSchema)
    where
      queuedNotificationListDoc :: NamedSwaggerDoc -> NamedSwaggerDoc
queuedNotificationListDoc = (Maybe Text -> Identity (Maybe Text))
-> NamedSwaggerDoc -> Identity NamedSwaggerDoc
forall s a. HasDescription s a => Lens' s a
Lens' NamedSwaggerDoc (Maybe Text)
description ((Maybe Text -> Identity (Maybe Text))
 -> NamedSwaggerDoc -> Identity NamedSwaggerDoc)
-> Text -> NamedSwaggerDoc -> NamedSwaggerDoc
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ Text
"Zero or more notifications"
      notificationsDoc :: SwaggerDoc -> SwaggerDoc
notificationsDoc = (Maybe Text -> Identity (Maybe Text))
-> SwaggerDoc -> Identity SwaggerDoc
forall s a. HasDescription s a => Lens' s a
Lens' SwaggerDoc (Maybe Text)
description ((Maybe Text -> Identity (Maybe Text))
 -> SwaggerDoc -> Identity SwaggerDoc)
-> Text -> SwaggerDoc -> SwaggerDoc
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ Text
"Notifications"
      hasMoreDoc :: NamedSwaggerDoc -> NamedSwaggerDoc
hasMoreDoc = (Maybe Text -> Identity (Maybe Text))
-> NamedSwaggerDoc -> Identity NamedSwaggerDoc
forall s a. HasDescription s a => Lens' s a
Lens' NamedSwaggerDoc (Maybe Text)
description ((Maybe Text -> Identity (Maybe Text))
 -> NamedSwaggerDoc -> Identity NamedSwaggerDoc)
-> Text -> NamedSwaggerDoc -> NamedSwaggerDoc
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ Text
"Whether there are still more notifications."

makeLenses ''QueuedNotificationList

newtype RawNotificationId = RawNotificationId {RawNotificationId -> ByteString
unRawNotificationId :: ByteString}
  deriving stock (RawNotificationId -> RawNotificationId -> Bool
(RawNotificationId -> RawNotificationId -> Bool)
-> (RawNotificationId -> RawNotificationId -> Bool)
-> Eq RawNotificationId
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: RawNotificationId -> RawNotificationId -> Bool
== :: RawNotificationId -> RawNotificationId -> Bool
$c/= :: RawNotificationId -> RawNotificationId -> Bool
/= :: RawNotificationId -> RawNotificationId -> Bool
Eq, Int -> RawNotificationId -> ShowS
[RawNotificationId] -> ShowS
RawNotificationId -> String
(Int -> RawNotificationId -> ShowS)
-> (RawNotificationId -> String)
-> ([RawNotificationId] -> ShowS)
-> Show RawNotificationId
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> RawNotificationId -> ShowS
showsPrec :: Int -> RawNotificationId -> ShowS
$cshow :: RawNotificationId -> String
show :: RawNotificationId -> String
$cshowList :: [RawNotificationId] -> ShowS
showList :: [RawNotificationId] -> ShowS
Show, (forall x. RawNotificationId -> Rep RawNotificationId x)
-> (forall x. Rep RawNotificationId x -> RawNotificationId)
-> Generic RawNotificationId
forall x. Rep RawNotificationId x -> RawNotificationId
forall x. RawNotificationId -> Rep RawNotificationId x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. RawNotificationId -> Rep RawNotificationId x
from :: forall x. RawNotificationId -> Rep RawNotificationId x
$cto :: forall x. Rep RawNotificationId x -> RawNotificationId
to :: forall x. Rep RawNotificationId x -> RawNotificationId
Generic)

instance FromHttpApiData RawNotificationId where
  parseUrlPiece :: Text -> Either Text RawNotificationId
parseUrlPiece = RawNotificationId -> Either Text RawNotificationId
forall a. a -> Either Text a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (RawNotificationId -> Either Text RawNotificationId)
-> (Text -> RawNotificationId)
-> Text
-> Either Text RawNotificationId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> RawNotificationId
RawNotificationId (ByteString -> RawNotificationId)
-> (Text -> ByteString) -> Text -> RawNotificationId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
encodeUtf8

instance ToParamSchema RawNotificationId where
  toParamSchema :: Proxy RawNotificationId -> Schema
toParamSchema Proxy RawNotificationId
_ = Proxy Text -> Schema
forall a. ToParamSchema a => Proxy a -> Schema
toParamSchema (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @Text)

data GetNotificationsResponse
  = GetNotificationsWithStatusNotFound QueuedNotificationList
  | GetNotificationsSuccess QueuedNotificationList

instance AsUnion '[Respond 404 "Notification list" QueuedNotificationList, Respond 200 "Notification list" QueuedNotificationList] GetNotificationsResponse where
  toUnion :: GetNotificationsResponse
-> Union
     (ResponseTypes
        '[Respond 404 "Notification list" QueuedNotificationList,
          Respond 200 "Notification list" QueuedNotificationList])
toUnion (GetNotificationsSuccess QueuedNotificationList
xs) = NS I '[QueuedNotificationList]
-> NS I '[QueuedNotificationList, QueuedNotificationList]
forall {k} (a :: k -> *) (xs :: [k]) (x :: k).
NS a xs -> NS a (x : xs)
S (I QueuedNotificationList -> NS I '[QueuedNotificationList]
forall {k} (a :: k -> *) (x :: k) (xs :: [k]). a x -> NS a (x : xs)
Z (QueuedNotificationList -> I QueuedNotificationList
forall a. a -> I a
I QueuedNotificationList
xs))
  toUnion (GetNotificationsWithStatusNotFound QueuedNotificationList
xs) = I QueuedNotificationList
-> NS I '[QueuedNotificationList, QueuedNotificationList]
forall {k} (a :: k -> *) (x :: k) (xs :: [k]). a x -> NS a (x : xs)
Z (QueuedNotificationList -> I QueuedNotificationList
forall a. a -> I a
I QueuedNotificationList
xs)
  fromUnion :: Union
  (ResponseTypes
     '[Respond 404 "Notification list" QueuedNotificationList,
       Respond 200 "Notification list" QueuedNotificationList])
-> GetNotificationsResponse
fromUnion (S (Z (I x
xs))) = QueuedNotificationList -> GetNotificationsResponse
GetNotificationsSuccess x
QueuedNotificationList
xs
  fromUnion (Z (I x
xs)) = QueuedNotificationList -> GetNotificationsResponse
GetNotificationsWithStatusNotFound x
QueuedNotificationList
xs
  fromUnion (S (S NS I xs
x)) = case NS I xs
x of {}