-- 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.MLS.Extension 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-7.2-2
data Extension = Extension
  { Extension -> Word16
extType :: Word16,
    Extension -> ByteString
extData :: ByteString
  }
  deriving stock (Extension -> Extension -> Bool
(Extension -> Extension -> Bool)
-> (Extension -> Extension -> Bool) -> Eq Extension
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Extension -> Extension -> Bool
== :: Extension -> Extension -> Bool
$c/= :: Extension -> Extension -> Bool
/= :: Extension -> Extension -> Bool
Eq, Int -> Extension -> ShowS
[Extension] -> ShowS
Extension -> String
(Int -> Extension -> ShowS)
-> (Extension -> String)
-> ([Extension] -> ShowS)
-> Show Extension
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Extension -> ShowS
showsPrec :: Int -> Extension -> ShowS
$cshow :: Extension -> String
show :: Extension -> String
$cshowList :: [Extension] -> ShowS
showList :: [Extension] -> ShowS
Show, (forall x. Extension -> Rep Extension x)
-> (forall x. Rep Extension x -> Extension) -> Generic Extension
forall x. Rep Extension x -> Extension
forall x. Extension -> Rep Extension x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Extension -> Rep Extension x
from :: forall x. Extension -> Rep Extension x
$cto :: forall x. Rep Extension x -> Extension
to :: forall x. Rep Extension x -> Extension
Generic)
  deriving (Gen Extension
Gen Extension -> (Extension -> [Extension]) -> Arbitrary Extension
Extension -> [Extension]
forall a. Gen a -> (a -> [a]) -> Arbitrary a
$carbitrary :: Gen Extension
arbitrary :: Gen Extension
$cshrink :: Extension -> [Extension]
shrink :: Extension -> [Extension]
Arbitrary) via GenericUniform Extension

instance ParseMLS Extension where
  parseMLS :: Get Extension
parseMLS = Word16 -> ByteString -> Extension
Extension (Word16 -> ByteString -> Extension)
-> Get Word16 -> Get (ByteString -> Extension)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word16
forall a. ParseMLS a => Get a
parseMLS Get (ByteString -> Extension) -> Get ByteString -> Get Extension
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall w. (Binary w, Integral w) => Get ByteString
parseMLSBytes @VarInt

instance SerialiseMLS Extension where
  serialiseMLS :: Extension -> Put
serialiseMLS (Extension Word16
ty ByteString
d) = do
    Word16 -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS Word16
ty
    forall w. (Binary w, Integral w) => ByteString -> Put
serialiseMLSBytes @VarInt ByteString
d