content: {-# LANGUAGE StrictData #-}
  
  -- 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/>.
  
  -- | This module is deprecated and only used for old endpoints to send messages.
  -- The new protobuf definitions are generated using proto-lens in the wire-message-proto-lens package.
  module Wire.API.Message.Proto
    ( UserId,
      userId,
      fromUserId,
      ClientId,
      newClientId,
      fromClientId,
      toClientId,
      ClientEntry,
      clientEntry,
      clientEntryId,
      clientEntryMessage,
      UserEntry,
      userEntry,
      userEntryId,
      userEntryClients,
      Priority (..),
      NewOtrMessage,
      newOtrMessage,
      newOtrMessageSender,
      newOtrMessageRecipients,
      newOtrMessageNativePush,
      newOtrMessageNativePriority,
      newOtrMessageData,
      newOtrMessageTransient,
      newOtrMessageReportMissing,
    )
  where
  
  import Data.Id qualified as Id
  import Data.ProtocolBuffers
  import Imports
  
  --------------------------------------------------------------------------------
  -- UserId
  
  newtype UserId = UserId
    { _user :: Required 1 (Value Id.UserId)
    }
    deriving stock (Eq, Show, Generic)
  
  instance Encode UserId
  
  instance Decode UserId
  
  fromUserId :: Id.UserId -> UserId
  fromUserId u = UserId {_user = putField u}
  
  userId :: (Functor f) => (Id.UserId -> f Id.UserId) -> UserId -> f UserId
  userId f c = (\x -> c {_user = x}) <$> field f (_user c)
  
  --------------------------------------------------------------------------------
  -- ClientId
  
  newtype ClientId = ClientId
    { _client :: Required 1 (Value Word64)
    }
    deriving stock (Eq, Show, Generic)
  
  instance Encode ClientId
  
  instance Decode ClientId
  
  newClientId :: Word64 -> ClientId
  newClientId c = ClientId {_client = putField c}
  
  toClientId :: ClientId -> Id.ClientId
  toClientId c = Id.ClientId $ getField (_client c)
  
  fromClientId :: Id.ClientId -> ClientId
  fromClientId = newClientId . Id.clientToWord64
  
  --------------------------------------------------------------------------------
  -- ClientEntry
  
  data ClientEntry = ClientEntry
    { _clientId :: Required 1 (Message ClientId),
      _clientVal :: Required 2 (Value ByteString)
    }
    deriving stock (Eq, Show, Generic)
  
  instance Encode ClientEntry
  
  instance Decode ClientEntry
  
  clientEntry :: ClientId -> ByteString -> ClientEntry
  clientEntry c t =
    ClientEntry
      { _clientId = putField c,
        _clientVal = putField t
      }
  
  clientEntryId :: (Functor f) => (ClientId -> f ClientId) -> ClientEntry -> f ClientEntry
  clientEntryId f c = (\x -> c {_clientId = x}) <$> field f (_clientId c)
  
  clientEntryMessage :: (Functor f) => (ByteString -> f ByteString) -> ClientEntry -> f ClientEntry
  clientEntryMessage f c = (\x -> c {_clientVal = x}) <$> field f (_clientVal c)
  
  --------------------------------------------------------------------------------
  -- UserEntry
  
  data UserEntry = UserEntry
    { _userId :: Required 1 (Message UserId),
      _userVal :: Repeated 2 (Message ClientEntry)
    }
    deriving stock (Eq, Show, Generic)
  
  instance Encode UserEntry
  
  instance Decode UserEntry
  
  userEntry :: UserId -> [ClientEntry] -> UserEntry
  userEntry u c =
    UserEntry
      { _userId = putField u,
        _userVal = putField c
      }
  
  userEntryId :: (Functor f) => (UserId -> f UserId) -> UserEntry -> f UserEntry
  userEntryId f c = (\x -> c {_userId = x}) <$> field f (_userId c)
  
  userEntryClients :: (Functor f) => ([ClientEntry] -> f [ClientEntry]) -> UserEntry -> f UserEntry
  userEntryClients f c = (\x -> c {_userVal = x}) <$> field f (_userVal c)
  
  --------------------------------------------------------------------------------
  -- Priority
  
  -- | See also `Wire.API.Message.Priority`
  data Priority = LowPriority | HighPriority
    deriving stock (Eq, Show, Ord, Generic)
  
  instance Encode Priority
  
  instance Decode Priority
  
  instance Enum Priority where
    toEnum 1 = LowPriority
    toEnum 2 = HighPriority
    toEnum x = error $ "Wire.API.Message.Proto.Priority: invalid enum value: " ++ show x
  
    fromEnum LowPriority = 1
    fromEnum HighPriority = 2
  
  instance Bounded Priority where
    minBound = LowPriority
    maxBound = HighPriority
  
  --------------------------------------------------------------------------------
  -- NewOtrMessage
  
  data NewOtrMessage = NewOtrMessage
    { _newOtrSender :: Required 1 (Message ClientId),
      _newOtrRecipients :: Repeated 2 (Message UserEntry),
      _newOtrNativePush :: Optional 3 (Value Bool),
      _newOtrData :: Optional 4 (Value ByteString),
      _newOtrNativePriority :: Optional 5 (Enumeration Priority), -- See note [orphans]
      _newOtrTransient :: Optional 6 (Value Bool),
      _newOtrReportMissing :: Repeated 7 (Message UserId)
    }
    deriving stock (Eq, Show, Generic)
  
  instance Encode NewOtrMessage
  
  instance Decode NewOtrMessage
  
  newOtrMessage :: ClientId -> [UserEntry] -> NewOtrMessage
  newOtrMessage c us =
    NewOtrMessage
      { _newOtrSender = putField c,
        _newOtrRecipients = putField us,
        _newOtrNativePush = putField Nothing,
        _newOtrData = putField Nothing,
        _newOtrNativePriority = putField Nothing,
        _newOtrTransient = putField Nothing,
        _newOtrReportMissing = putField []
      }
  
  newOtrMessageSender :: (Functor f) => (ClientId -> f ClientId) -> NewOtrMessage -> f NewOtrMessage
  newOtrMessageSender f c = (\x -> c {_newOtrSender = x}) <$> field f (_newOtrSender c)
  
  newOtrMessageRecipients :: (Functor f) => ([UserEntry] -> f [UserEntry]) -> NewOtrMessage -> f NewOtrMessage
  newOtrMessageRecipients f c = (\x -> c {_newOtrRecipients = x}) <$> field f (_newOtrRecipients c)
  
  newOtrMessageNativePush :: (Functor f) => (Bool -> f Bool) -> NewOtrMessage -> f NewOtrMessage
  newOtrMessageNativePush f c =
    let g x = Just <$> f (fromMaybe True x)
     in (\x -> c {_newOtrNativePush = x}) <$> field g (_newOtrNativePush c)
  
  newOtrMessageTransient :: (Functor f) => (Bool -> f Bool) -> NewOtrMessage -> f NewOtrMessage
  newOtrMessageTransient f c =
    let g x = Just <$> f (fromMaybe False x)
     in (\x -> c {_newOtrTransient = x}) <$> field g (_newOtrTransient c)
  
  newOtrMessageData :: (Functor f) => (Maybe ByteString -> f (Maybe ByteString)) -> NewOtrMessage -> f NewOtrMessage
  newOtrMessageData f c = (\x -> c {_newOtrData = x}) <$> field f (_newOtrData c)
  
  newOtrMessageNativePriority :: (Functor f) => (Maybe Priority -> f (Maybe Priority)) -> NewOtrMessage -> f NewOtrMessage
  newOtrMessageNativePriority f c = (\x -> c {_newOtrNativePriority = x}) <$> field f (_newOtrNativePriority c)
  
  newOtrMessageReportMissing :: (Functor f) => ([UserId] -> f [UserId]) -> NewOtrMessage -> f NewOtrMessage
  newOtrMessageReportMissing f c = (\x -> c {_newOtrReportMissing = x}) <$> field f (_newOtrReportMissing c)
  