module Wire.API.Event.Federation
  ( Event (..),
    EventType (..),
  )
where

import Data.Aeson (FromJSON, ToJSON)
import Data.Aeson qualified as A
import Data.Aeson.KeyMap qualified as KeyMap
import Data.Domain
import Data.Json.Util (ToJSONObject (toJSONObject))
import Data.OpenApi qualified as S
import Data.Schema
import Imports
import Wire.Arbitrary

data Event = Event
  { Event -> EventType
_eventType :: EventType,
    Event -> Domain
_eventDomain :: Domain
  }
  deriving (Event -> Event -> Bool
(Event -> Event -> Bool) -> (Event -> Event -> Bool) -> Eq Event
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Event -> Event -> Bool
== :: Event -> Event -> Bool
$c/= :: Event -> Event -> Bool
/= :: Event -> Event -> Bool
Eq, Int -> Event -> ShowS
[Event] -> ShowS
Event -> String
(Int -> Event -> ShowS)
-> (Event -> String) -> ([Event] -> ShowS) -> Show Event
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Event -> ShowS
showsPrec :: Int -> Event -> ShowS
$cshow :: Event -> String
show :: Event -> String
$cshowList :: [Event] -> ShowS
showList :: [Event] -> ShowS
Show, Eq Event
Eq Event =>
(Event -> Event -> Ordering)
-> (Event -> Event -> Bool)
-> (Event -> Event -> Bool)
-> (Event -> Event -> Bool)
-> (Event -> Event -> Bool)
-> (Event -> Event -> Event)
-> (Event -> Event -> Event)
-> Ord Event
Event -> Event -> Bool
Event -> Event -> Ordering
Event -> Event -> Event
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Event -> Event -> Ordering
compare :: Event -> Event -> Ordering
$c< :: Event -> Event -> Bool
< :: Event -> Event -> Bool
$c<= :: Event -> Event -> Bool
<= :: Event -> Event -> Bool
$c> :: Event -> Event -> Bool
> :: Event -> Event -> Bool
$c>= :: Event -> Event -> Bool
>= :: Event -> Event -> Bool
$cmax :: Event -> Event -> Event
max :: Event -> Event -> Event
$cmin :: Event -> Event -> Event
min :: Event -> Event -> Event
Ord, (forall x. Event -> Rep Event x)
-> (forall x. Rep Event x -> Event) -> Generic Event
forall x. Rep Event x -> Event
forall x. Event -> Rep Event x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Event -> Rep Event x
from :: forall x. Event -> Rep Event x
$cto :: forall x. Rep Event x -> Event
to :: forall x. Rep Event x -> Event
Generic)

instance Arbitrary Event where
  arbitrary :: Gen Event
arbitrary =
    EventType -> Domain -> Event
Event
      (EventType -> Domain -> Event)
-> Gen EventType -> Gen (Domain -> Event)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen EventType
forall a. Arbitrary a => Gen a
arbitrary
      Gen (Domain -> Event) -> Gen Domain -> Gen Event
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen Domain
forall a. Arbitrary a => Gen a
arbitrary

data EventType
  = FederationDelete
  deriving (EventType -> EventType -> Bool
(EventType -> EventType -> Bool)
-> (EventType -> EventType -> Bool) -> Eq EventType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: EventType -> EventType -> Bool
== :: EventType -> EventType -> Bool
$c/= :: EventType -> EventType -> Bool
/= :: EventType -> EventType -> Bool
Eq, Int -> EventType -> ShowS
[EventType] -> ShowS
EventType -> String
(Int -> EventType -> ShowS)
-> (EventType -> String)
-> ([EventType] -> ShowS)
-> Show EventType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> EventType -> ShowS
showsPrec :: Int -> EventType -> ShowS
$cshow :: EventType -> String
show :: EventType -> String
$cshowList :: [EventType] -> ShowS
showList :: [EventType] -> ShowS
Show, Eq EventType
Eq EventType =>
(EventType -> EventType -> Ordering)
-> (EventType -> EventType -> Bool)
-> (EventType -> EventType -> Bool)
-> (EventType -> EventType -> Bool)
-> (EventType -> EventType -> Bool)
-> (EventType -> EventType -> EventType)
-> (EventType -> EventType -> EventType)
-> Ord EventType
EventType -> EventType -> Bool
EventType -> EventType -> Ordering
EventType -> EventType -> EventType
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: EventType -> EventType -> Ordering
compare :: EventType -> EventType -> Ordering
$c< :: EventType -> EventType -> Bool
< :: EventType -> EventType -> Bool
$c<= :: EventType -> EventType -> Bool
<= :: EventType -> EventType -> Bool
$c> :: EventType -> EventType -> Bool
> :: EventType -> EventType -> Bool
$c>= :: EventType -> EventType -> Bool
>= :: EventType -> EventType -> Bool
$cmax :: EventType -> EventType -> EventType
max :: EventType -> EventType -> EventType
$cmin :: EventType -> EventType -> EventType
min :: EventType -> EventType -> EventType
Ord, (forall x. EventType -> Rep EventType x)
-> (forall x. Rep EventType x -> EventType) -> Generic EventType
forall x. Rep EventType x -> EventType
forall x. EventType -> Rep EventType x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. EventType -> Rep EventType x
from :: forall x. EventType -> Rep EventType x
$cto :: forall x. Rep EventType x -> EventType
to :: forall x. Rep EventType x -> EventType
Generic)
  deriving (Gen EventType
Gen EventType -> (EventType -> [EventType]) -> Arbitrary EventType
EventType -> [EventType]
forall a. Gen a -> (a -> [a]) -> Arbitrary a
$carbitrary :: Gen EventType
arbitrary :: Gen EventType
$cshrink :: EventType -> [EventType]
shrink :: EventType -> [EventType]
Arbitrary) via (GenericUniform EventType)
  deriving (Value -> Parser [EventType]
Value -> Parser EventType
(Value -> Parser EventType)
-> (Value -> Parser [EventType]) -> FromJSON EventType
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
$cparseJSON :: Value -> Parser EventType
parseJSON :: Value -> Parser EventType
$cparseJSONList :: Value -> Parser [EventType]
parseJSONList :: Value -> Parser [EventType]
A.FromJSON, [EventType] -> Value
[EventType] -> Encoding
EventType -> Value
EventType -> Encoding
(EventType -> Value)
-> (EventType -> Encoding)
-> ([EventType] -> Value)
-> ([EventType] -> Encoding)
-> ToJSON EventType
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
$ctoJSON :: EventType -> Value
toJSON :: EventType -> Value
$ctoEncoding :: EventType -> Encoding
toEncoding :: EventType -> Encoding
$ctoJSONList :: [EventType] -> Value
toJSONList :: [EventType] -> Value
$ctoEncodingList :: [EventType] -> Encoding
toEncodingList :: [EventType] -> Encoding
A.ToJSON, Typeable EventType
Typeable EventType =>
(Proxy EventType -> Declare (Definitions Schema) NamedSchema)
-> ToSchema EventType
Proxy EventType -> Declare (Definitions Schema) NamedSchema
forall a.
Typeable a =>
(Proxy a -> Declare (Definitions Schema) NamedSchema) -> ToSchema a
$cdeclareNamedSchema :: Proxy EventType -> Declare (Definitions Schema) NamedSchema
declareNamedSchema :: Proxy EventType -> Declare (Definitions Schema) NamedSchema
S.ToSchema) via Schema EventType

instance ToSchema EventType where
  schema :: ValueSchema NamedSwaggerDoc EventType
schema =
    forall v doc a b.
(With v, HasEnum v doc) =>
Text
-> SchemaP [Value] v (Alt Maybe v) a b
-> SchemaP doc Value Value a b
enum @Text Text
"EventType" (SchemaP [Value] Text (Alt Maybe Text) EventType EventType
 -> ValueSchema NamedSwaggerDoc EventType)
-> SchemaP [Value] Text (Alt Maybe Text) EventType EventType
-> ValueSchema NamedSwaggerDoc EventType
forall a b. (a -> b) -> a -> b
$
      [SchemaP [Value] Text (Alt Maybe Text) EventType EventType]
-> SchemaP [Value] Text (Alt Maybe Text) EventType EventType
forall a. Monoid a => [a] -> a
mconcat
        [ Text
-> EventType
-> SchemaP [Value] Text (Alt Maybe Text) EventType EventType
forall a b.
(ToJSON a, Eq a, Eq b) =>
a -> b -> SchemaP [Value] a (Alt Maybe a) b b
element Text
"federation.delete" EventType
FederationDelete
        ]

eventObjectSchema :: ObjectSchema SwaggerDoc Event
eventObjectSchema :: ObjectSchema SwaggerDoc Event
eventObjectSchema =
  EventType -> Domain -> Event
Event
    (EventType -> Domain -> Event)
-> SchemaP SwaggerDoc Object [Pair] Event EventType
-> SchemaP SwaggerDoc Object [Pair] Event (Domain -> Event)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Event -> EventType
_eventType (Event -> EventType)
-> SchemaP SwaggerDoc Object [Pair] EventType EventType
-> SchemaP SwaggerDoc Object [Pair] Event EventType
forall (p :: * -> * -> *) a a' b.
Profunctor p =>
(a -> a') -> p a' b -> p a b
.= Text
-> ValueSchema NamedSwaggerDoc EventType
-> SchemaP SwaggerDoc Object [Pair] EventType EventType
forall doc' doc a b.
HasField doc' doc =>
Text
-> SchemaP doc' Value Value a b -> SchemaP doc Object [Pair] a b
field Text
"type" ValueSchema NamedSwaggerDoc EventType
forall a. ToSchema a => ValueSchema NamedSwaggerDoc a
schema
    SchemaP SwaggerDoc Object [Pair] Event (Domain -> Event)
-> SchemaP SwaggerDoc Object [Pair] Event Domain
-> ObjectSchema SwaggerDoc Event
forall a b.
SchemaP SwaggerDoc Object [Pair] Event (a -> b)
-> SchemaP SwaggerDoc Object [Pair] Event a
-> SchemaP SwaggerDoc Object [Pair] Event b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Event -> Domain
_eventDomain (Event -> Domain)
-> SchemaP SwaggerDoc Object [Pair] Domain Domain
-> SchemaP SwaggerDoc Object [Pair] Event Domain
forall (p :: * -> * -> *) a a' b.
Profunctor p =>
(a -> a') -> p a' b -> p a b
.= Text
-> SchemaP NamedSwaggerDoc Value Value Domain Domain
-> SchemaP SwaggerDoc Object [Pair] Domain Domain
forall doc' doc a b.
HasField doc' doc =>
Text
-> SchemaP doc' Value Value a b -> SchemaP doc Object [Pair] a b
field Text
"domain" SchemaP NamedSwaggerDoc Value Value Domain Domain
forall a. ToSchema a => ValueSchema NamedSwaggerDoc a
schema

instance ToSchema Event where
  schema :: ValueSchema NamedSwaggerDoc Event
schema = Text
-> ObjectSchema SwaggerDoc Event
-> ValueSchema NamedSwaggerDoc Event
forall doc doc' a b.
HasObject doc doc' =>
Text
-> SchemaP doc Object [Pair] a b -> SchemaP doc' Value Value a b
object Text
"Event" ObjectSchema SwaggerDoc Event
eventObjectSchema

instance ToJSONObject Event where
  toJSONObject :: Event -> Object
toJSONObject =
    [Pair] -> Object
forall v. [(Key, v)] -> KeyMap v
KeyMap.fromList
      ([Pair] -> Object) -> (Event -> [Pair]) -> Event -> Object
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Pair] -> Maybe [Pair] -> [Pair]
forall a. a -> Maybe a -> a
fromMaybe []
      (Maybe [Pair] -> [Pair])
-> (Event -> Maybe [Pair]) -> Event -> [Pair]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ObjectSchema SwaggerDoc Event -> Event -> Maybe [Pair]
forall ss v m a b. SchemaP ss v m a b -> a -> Maybe m
schemaOut ObjectSchema SwaggerDoc Event
eventObjectSchema

instance S.ToSchema Event where
  declareNamedSchema :: Proxy Event -> Declare (Definitions Schema) NamedSchema
declareNamedSchema = Proxy Event -> Declare (Definitions Schema) NamedSchema
forall a.
ToSchema a =>
Proxy a -> Declare (Definitions Schema) NamedSchema
schemaToSwagger

instance FromJSON Event where
  parseJSON :: Value -> Parser Event
parseJSON = Value -> Parser Event
forall a. ToSchema a => Value -> Parser a
schemaParseJSON

instance ToJSON Event where
  toJSON :: Event -> Value
toJSON = Event -> Value
forall a. ToSchema a => a -> Value
schemaToJSON