-- 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/>.
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

module Wire.API.MLS.ProtocolVersion
  ( ProtocolVersion (..),
    ProtocolVersionTag (..),
    pvTag,
    protocolVersionFromTag,
    defaultProtocolVersion,
  )
where

import Data.Binary
import Imports
import Wire.API.MLS.Serialisation
import Wire.Arbitrary

-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-6-4
newtype ProtocolVersion = ProtocolVersion {ProtocolVersion -> Word16
pvNumber :: Word16}
  deriving newtype (ProtocolVersion -> ProtocolVersion -> Bool
(ProtocolVersion -> ProtocolVersion -> Bool)
-> (ProtocolVersion -> ProtocolVersion -> Bool)
-> Eq ProtocolVersion
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ProtocolVersion -> ProtocolVersion -> Bool
== :: ProtocolVersion -> ProtocolVersion -> Bool
$c/= :: ProtocolVersion -> ProtocolVersion -> Bool
/= :: ProtocolVersion -> ProtocolVersion -> Bool
Eq, Eq ProtocolVersion
Eq ProtocolVersion =>
(ProtocolVersion -> ProtocolVersion -> Ordering)
-> (ProtocolVersion -> ProtocolVersion -> Bool)
-> (ProtocolVersion -> ProtocolVersion -> Bool)
-> (ProtocolVersion -> ProtocolVersion -> Bool)
-> (ProtocolVersion -> ProtocolVersion -> Bool)
-> (ProtocolVersion -> ProtocolVersion -> ProtocolVersion)
-> (ProtocolVersion -> ProtocolVersion -> ProtocolVersion)
-> Ord ProtocolVersion
ProtocolVersion -> ProtocolVersion -> Bool
ProtocolVersion -> ProtocolVersion -> Ordering
ProtocolVersion -> ProtocolVersion -> ProtocolVersion
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 :: ProtocolVersion -> ProtocolVersion -> Ordering
compare :: ProtocolVersion -> ProtocolVersion -> Ordering
$c< :: ProtocolVersion -> ProtocolVersion -> Bool
< :: ProtocolVersion -> ProtocolVersion -> Bool
$c<= :: ProtocolVersion -> ProtocolVersion -> Bool
<= :: ProtocolVersion -> ProtocolVersion -> Bool
$c> :: ProtocolVersion -> ProtocolVersion -> Bool
> :: ProtocolVersion -> ProtocolVersion -> Bool
$c>= :: ProtocolVersion -> ProtocolVersion -> Bool
>= :: ProtocolVersion -> ProtocolVersion -> Bool
$cmax :: ProtocolVersion -> ProtocolVersion -> ProtocolVersion
max :: ProtocolVersion -> ProtocolVersion -> ProtocolVersion
$cmin :: ProtocolVersion -> ProtocolVersion -> ProtocolVersion
min :: ProtocolVersion -> ProtocolVersion -> ProtocolVersion
Ord, Int -> ProtocolVersion -> ShowS
[ProtocolVersion] -> ShowS
ProtocolVersion -> String
(Int -> ProtocolVersion -> ShowS)
-> (ProtocolVersion -> String)
-> ([ProtocolVersion] -> ShowS)
-> Show ProtocolVersion
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ProtocolVersion -> ShowS
showsPrec :: Int -> ProtocolVersion -> ShowS
$cshow :: ProtocolVersion -> String
show :: ProtocolVersion -> String
$cshowList :: [ProtocolVersion] -> ShowS
showList :: [ProtocolVersion] -> ShowS
Show, Get ProtocolVersion
[ProtocolVersion] -> Put
ProtocolVersion -> Put
(ProtocolVersion -> Put)
-> Get ProtocolVersion
-> ([ProtocolVersion] -> Put)
-> Binary ProtocolVersion
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
$cput :: ProtocolVersion -> Put
put :: ProtocolVersion -> Put
$cget :: Get ProtocolVersion
get :: Get ProtocolVersion
$cputList :: [ProtocolVersion] -> Put
putList :: [ProtocolVersion] -> Put
Binary, Gen ProtocolVersion
Gen ProtocolVersion
-> (ProtocolVersion -> [ProtocolVersion])
-> Arbitrary ProtocolVersion
ProtocolVersion -> [ProtocolVersion]
forall a. Gen a -> (a -> [a]) -> Arbitrary a
$carbitrary :: Gen ProtocolVersion
arbitrary :: Gen ProtocolVersion
$cshrink :: ProtocolVersion -> [ProtocolVersion]
shrink :: ProtocolVersion -> [ProtocolVersion]
Arbitrary, Get ProtocolVersion
Get ProtocolVersion -> ParseMLS ProtocolVersion
forall a. Get a -> ParseMLS a
$cparseMLS :: Get ProtocolVersion
parseMLS :: Get ProtocolVersion
ParseMLS, ProtocolVersion -> Put
(ProtocolVersion -> Put) -> SerialiseMLS ProtocolVersion
forall a. (a -> Put) -> SerialiseMLS a
$cserialiseMLS :: ProtocolVersion -> Put
serialiseMLS :: ProtocolVersion -> Put
SerialiseMLS)

data ProtocolVersionTag = ProtocolMLS10 | ProtocolMLSDraft11
  deriving stock (ProtocolVersionTag
ProtocolVersionTag
-> ProtocolVersionTag -> Bounded ProtocolVersionTag
forall a. a -> a -> Bounded a
$cminBound :: ProtocolVersionTag
minBound :: ProtocolVersionTag
$cmaxBound :: ProtocolVersionTag
maxBound :: ProtocolVersionTag
Bounded, Int -> ProtocolVersionTag
ProtocolVersionTag -> Int
ProtocolVersionTag -> [ProtocolVersionTag]
ProtocolVersionTag -> ProtocolVersionTag
ProtocolVersionTag -> ProtocolVersionTag -> [ProtocolVersionTag]
ProtocolVersionTag
-> ProtocolVersionTag -> ProtocolVersionTag -> [ProtocolVersionTag]
(ProtocolVersionTag -> ProtocolVersionTag)
-> (ProtocolVersionTag -> ProtocolVersionTag)
-> (Int -> ProtocolVersionTag)
-> (ProtocolVersionTag -> Int)
-> (ProtocolVersionTag -> [ProtocolVersionTag])
-> (ProtocolVersionTag
    -> ProtocolVersionTag -> [ProtocolVersionTag])
-> (ProtocolVersionTag
    -> ProtocolVersionTag -> [ProtocolVersionTag])
-> (ProtocolVersionTag
    -> ProtocolVersionTag
    -> ProtocolVersionTag
    -> [ProtocolVersionTag])
-> Enum ProtocolVersionTag
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: ProtocolVersionTag -> ProtocolVersionTag
succ :: ProtocolVersionTag -> ProtocolVersionTag
$cpred :: ProtocolVersionTag -> ProtocolVersionTag
pred :: ProtocolVersionTag -> ProtocolVersionTag
$ctoEnum :: Int -> ProtocolVersionTag
toEnum :: Int -> ProtocolVersionTag
$cfromEnum :: ProtocolVersionTag -> Int
fromEnum :: ProtocolVersionTag -> Int
$cenumFrom :: ProtocolVersionTag -> [ProtocolVersionTag]
enumFrom :: ProtocolVersionTag -> [ProtocolVersionTag]
$cenumFromThen :: ProtocolVersionTag -> ProtocolVersionTag -> [ProtocolVersionTag]
enumFromThen :: ProtocolVersionTag -> ProtocolVersionTag -> [ProtocolVersionTag]
$cenumFromTo :: ProtocolVersionTag -> ProtocolVersionTag -> [ProtocolVersionTag]
enumFromTo :: ProtocolVersionTag -> ProtocolVersionTag -> [ProtocolVersionTag]
$cenumFromThenTo :: ProtocolVersionTag
-> ProtocolVersionTag -> ProtocolVersionTag -> [ProtocolVersionTag]
enumFromThenTo :: ProtocolVersionTag
-> ProtocolVersionTag -> ProtocolVersionTag -> [ProtocolVersionTag]
Enum, ProtocolVersionTag -> ProtocolVersionTag -> Bool
(ProtocolVersionTag -> ProtocolVersionTag -> Bool)
-> (ProtocolVersionTag -> ProtocolVersionTag -> Bool)
-> Eq ProtocolVersionTag
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ProtocolVersionTag -> ProtocolVersionTag -> Bool
== :: ProtocolVersionTag -> ProtocolVersionTag -> Bool
$c/= :: ProtocolVersionTag -> ProtocolVersionTag -> Bool
/= :: ProtocolVersionTag -> ProtocolVersionTag -> Bool
Eq, Int -> ProtocolVersionTag -> ShowS
[ProtocolVersionTag] -> ShowS
ProtocolVersionTag -> String
(Int -> ProtocolVersionTag -> ShowS)
-> (ProtocolVersionTag -> String)
-> ([ProtocolVersionTag] -> ShowS)
-> Show ProtocolVersionTag
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ProtocolVersionTag -> ShowS
showsPrec :: Int -> ProtocolVersionTag -> ShowS
$cshow :: ProtocolVersionTag -> String
show :: ProtocolVersionTag -> String
$cshowList :: [ProtocolVersionTag] -> ShowS
showList :: [ProtocolVersionTag] -> ShowS
Show, (forall x. ProtocolVersionTag -> Rep ProtocolVersionTag x)
-> (forall x. Rep ProtocolVersionTag x -> ProtocolVersionTag)
-> Generic ProtocolVersionTag
forall x. Rep ProtocolVersionTag x -> ProtocolVersionTag
forall x. ProtocolVersionTag -> Rep ProtocolVersionTag x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ProtocolVersionTag -> Rep ProtocolVersionTag x
from :: forall x. ProtocolVersionTag -> Rep ProtocolVersionTag x
$cto :: forall x. Rep ProtocolVersionTag x -> ProtocolVersionTag
to :: forall x. Rep ProtocolVersionTag x -> ProtocolVersionTag
Generic)
  deriving (Gen ProtocolVersionTag
Gen ProtocolVersionTag
-> (ProtocolVersionTag -> [ProtocolVersionTag])
-> Arbitrary ProtocolVersionTag
ProtocolVersionTag -> [ProtocolVersionTag]
forall a. Gen a -> (a -> [a]) -> Arbitrary a
$carbitrary :: Gen ProtocolVersionTag
arbitrary :: Gen ProtocolVersionTag
$cshrink :: ProtocolVersionTag -> [ProtocolVersionTag]
shrink :: ProtocolVersionTag -> [ProtocolVersionTag]
Arbitrary) via GenericUniform ProtocolVersionTag

pvTag :: ProtocolVersion -> Maybe ProtocolVersionTag
pvTag :: ProtocolVersion -> Maybe ProtocolVersionTag
pvTag (ProtocolVersion Word16
v) = case Word16
v of
  Word16
1 -> ProtocolVersionTag -> Maybe ProtocolVersionTag
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ProtocolVersionTag
ProtocolMLS10
  -- used by openmls
  Word16
200 -> ProtocolVersionTag -> Maybe ProtocolVersionTag
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ProtocolVersionTag
ProtocolMLSDraft11
  Word16
_ -> Maybe ProtocolVersionTag
forall a. Maybe a
Nothing

protocolVersionFromTag :: ProtocolVersionTag -> ProtocolVersion
protocolVersionFromTag :: ProtocolVersionTag -> ProtocolVersion
protocolVersionFromTag ProtocolVersionTag
ProtocolMLS10 = Word16 -> ProtocolVersion
ProtocolVersion Word16
1
protocolVersionFromTag ProtocolVersionTag
ProtocolMLSDraft11 = Word16 -> ProtocolVersion
ProtocolVersion Word16
200

defaultProtocolVersion :: ProtocolVersion
defaultProtocolVersion :: ProtocolVersion
defaultProtocolVersion = ProtocolVersionTag -> ProtocolVersion
protocolVersionFromTag ProtocolVersionTag
ProtocolMLS10