module Hydra.Network.Ouroboros.Client where

import Hydra.Prelude

import Hydra.Network.Ouroboros.Type (
  ClientHasAgency (TokIdle),
  FireForget (..),
  Message (MsgDone, MsgSend),
  NobodyHasAgency (TokDone),
 )
import Network.TypedProtocol.Core (
  Peer (..),
  PeerHasAgency (..),
  PeerRole (..),
 )

data FireForgetClient msg m a where
  Idle :: m (FireForgetClient msg m a) -> FireForgetClient msg m a
  SendMsg :: msg -> m (FireForgetClient msg m a) -> FireForgetClient msg m a
  SendDone :: m a -> FireForgetClient msg m a

fireForgetClientPeer ::
  Monad m =>
  FireForgetClient msg m a ->
  Peer (FireForget msg) 'AsClient 'StIdle m a
fireForgetClientPeer :: forall (m :: * -> *) msg a.
Monad m =>
FireForgetClient msg m a
-> Peer (FireForget msg) 'AsClient 'StIdle m a
fireForgetClientPeer = \case
  Idle m (FireForgetClient msg m a)
next ->
    m (Peer (FireForget msg) 'AsClient 'StIdle m a)
-> Peer (FireForget msg) 'AsClient 'StIdle m a
forall (m :: * -> *) ps (pr :: PeerRole) (st :: ps) a.
m (Peer ps pr st m a) -> Peer ps pr st m a
Effect (m (Peer (FireForget msg) 'AsClient 'StIdle m a)
 -> Peer (FireForget msg) 'AsClient 'StIdle m a)
-> m (Peer (FireForget msg) 'AsClient 'StIdle m a)
-> Peer (FireForget msg) 'AsClient 'StIdle m a
forall a b. (a -> b) -> a -> b
$ FireForgetClient msg m a
-> Peer (FireForget msg) 'AsClient 'StIdle m a
forall (m :: * -> *) msg a.
Monad m =>
FireForgetClient msg m a
-> Peer (FireForget msg) 'AsClient 'StIdle m a
fireForgetClientPeer (FireForgetClient msg m a
 -> Peer (FireForget msg) 'AsClient 'StIdle m a)
-> m (FireForgetClient msg m a)
-> m (Peer (FireForget msg) 'AsClient 'StIdle m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (FireForgetClient msg m a)
next
  SendMsg msg
msg m (FireForgetClient msg m a)
next ->
    WeHaveAgency 'AsClient 'StIdle
-> Message (FireForget msg) 'StIdle 'StIdle
-> Peer (FireForget msg) 'AsClient 'StIdle m a
-> Peer (FireForget msg) 'AsClient 'StIdle m a
forall (pr :: PeerRole) ps (st :: ps) (st' :: ps) (m :: * -> *) a.
WeHaveAgency pr st
-> Message ps st st' -> Peer ps pr st' m a -> Peer ps pr st m a
Yield (ClientHasAgency 'StIdle -> WeHaveAgency 'AsClient 'StIdle
forall {ps} (st :: ps).
ClientHasAgency st -> PeerHasAgency 'AsClient st
ClientAgency ClientHasAgency 'StIdle
forall {k} {msg :: k}. ClientHasAgency 'StIdle
TokIdle) (msg -> Message (FireForget msg) 'StIdle 'StIdle
forall msg1. msg1 -> Message (FireForget msg1) 'StIdle 'StIdle
MsgSend msg
msg) (Peer (FireForget msg) 'AsClient 'StIdle m a
 -> Peer (FireForget msg) 'AsClient 'StIdle m a)
-> Peer (FireForget msg) 'AsClient 'StIdle m a
-> Peer (FireForget msg) 'AsClient 'StIdle m a
forall a b. (a -> b) -> a -> b
$
      m (Peer (FireForget msg) 'AsClient 'StIdle m a)
-> Peer (FireForget msg) 'AsClient 'StIdle m a
forall (m :: * -> *) ps (pr :: PeerRole) (st :: ps) a.
m (Peer ps pr st m a) -> Peer ps pr st m a
Effect (m (Peer (FireForget msg) 'AsClient 'StIdle m a)
 -> Peer (FireForget msg) 'AsClient 'StIdle m a)
-> m (Peer (FireForget msg) 'AsClient 'StIdle m a)
-> Peer (FireForget msg) 'AsClient 'StIdle m a
forall a b. (a -> b) -> a -> b
$
        FireForgetClient msg m a
-> Peer (FireForget msg) 'AsClient 'StIdle m a
forall (m :: * -> *) msg a.
Monad m =>
FireForgetClient msg m a
-> Peer (FireForget msg) 'AsClient 'StIdle m a
fireForgetClientPeer (FireForgetClient msg m a
 -> Peer (FireForget msg) 'AsClient 'StIdle m a)
-> m (FireForgetClient msg m a)
-> m (Peer (FireForget msg) 'AsClient 'StIdle m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (FireForgetClient msg m a)
next
  SendDone m a
action ->
    m (Peer (FireForget msg) 'AsClient 'StIdle m a)
-> Peer (FireForget msg) 'AsClient 'StIdle m a
forall (m :: * -> *) ps (pr :: PeerRole) (st :: ps) a.
m (Peer ps pr st m a) -> Peer ps pr st m a
Effect (m (Peer (FireForget msg) 'AsClient 'StIdle m a)
 -> Peer (FireForget msg) 'AsClient 'StIdle m a)
-> m (Peer (FireForget msg) 'AsClient 'StIdle m a)
-> Peer (FireForget msg) 'AsClient 'StIdle m a
forall a b. (a -> b) -> a -> b
$ WeHaveAgency 'AsClient 'StIdle
-> Message (FireForget msg) 'StIdle 'StDone
-> Peer (FireForget msg) 'AsClient 'StDone m a
-> Peer (FireForget msg) 'AsClient 'StIdle m a
forall (pr :: PeerRole) ps (st :: ps) (st' :: ps) (m :: * -> *) a.
WeHaveAgency pr st
-> Message ps st st' -> Peer ps pr st' m a -> Peer ps pr st m a
Yield (ClientHasAgency 'StIdle -> WeHaveAgency 'AsClient 'StIdle
forall {ps} (st :: ps).
ClientHasAgency st -> PeerHasAgency 'AsClient st
ClientAgency ClientHasAgency 'StIdle
forall {k} {msg :: k}. ClientHasAgency 'StIdle
TokIdle) Message (FireForget msg) 'StIdle 'StDone
forall {k} (msg :: k). Message (FireForget msg) 'StIdle 'StDone
MsgDone (Peer (FireForget msg) 'AsClient 'StDone m a
 -> Peer (FireForget msg) 'AsClient 'StIdle m a)
-> (a -> Peer (FireForget msg) 'AsClient 'StDone m a)
-> a
-> Peer (FireForget msg) 'AsClient 'StIdle m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NobodyHasAgency 'StDone
-> a -> Peer (FireForget msg) 'AsClient 'StDone m a
forall ps (st :: ps) a (pr :: PeerRole) (m :: * -> *).
NobodyHasAgency st -> a -> Peer ps pr st m a
Done NobodyHasAgency 'StDone
forall {k} {msg :: k}. NobodyHasAgency 'StDone
TokDone (a -> Peer (FireForget msg) 'AsClient 'StIdle m a)
-> m a -> m (Peer (FireForget msg) 'AsClient 'StIdle m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a
action