{-# LANGUAGE NamedFieldPuns      #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Ouroboros.Network.Protocol.LocalStateQuery.Direct (direct) where

import Ouroboros.Network.Protocol.LocalStateQuery.Client
import Ouroboros.Network.Protocol.LocalStateQuery.Server

direct
  :: forall block point query m a b.
     Monad m
  => LocalStateQueryClient block point query m a
  -> LocalStateQueryServer block point query m b
  -> m (a, b)
direct :: forall block point (query :: * -> *) (m :: * -> *) a b.
Monad m =>
LocalStateQueryClient block point query m a
-> LocalStateQueryServer block point query m b -> m (a, b)
direct (LocalStateQueryClient m (ClientStIdle block point query m a)
mclient) (LocalStateQueryServer m (ServerStIdle block point query m b)
mserver) = do
    client <- m (ClientStIdle block point query m a)
mclient
    server <- mserver
    directIdle client server
  where
    directIdle
      :: ClientStIdle block point query m a
      -> ServerStIdle block point query m b
      -> m (a, b)
    directIdle :: ClientStIdle block point query m a
-> ServerStIdle block point query m b -> m (a, b)
directIdle (SendMsgAcquire Target point
tgt ClientStAcquiring block point query m a
client') ServerStIdle{Target point -> m (ServerStAcquiring block point query m b)
recvMsgAcquire :: Target point -> m (ServerStAcquiring block point query m b)
recvMsgAcquire :: forall block point (query :: * -> *) (m :: * -> *) a.
ServerStIdle block point query m a
-> Target point -> m (ServerStAcquiring block point query m a)
recvMsgAcquire} = do
      server' <- Target point -> m (ServerStAcquiring block point query m b)
recvMsgAcquire Target point
tgt
      directAcquiring client' server'
    directIdle (SendMsgDone a
a) ServerStIdle{m b
recvMsgDone :: m b
recvMsgDone :: forall block point (query :: * -> *) (m :: * -> *) a.
ServerStIdle block point query m a -> m a
recvMsgDone} = do
      b <- m b
recvMsgDone
      return (a, b)

    directAcquiring
      :: ClientStAcquiring block point query m a
      -> ServerStAcquiring block point query m b
      -> m (a, b)
    directAcquiring :: ClientStAcquiring block point query m a
-> ServerStAcquiring block point query m b -> m (a, b)
directAcquiring ClientStAcquiring{m (ClientStAcquired block point query m a)
recvMsgAcquired :: m (ClientStAcquired block point query m a)
recvMsgAcquired :: forall block point (query :: * -> *) (m :: * -> *) a.
ClientStAcquiring block point query m a
-> m (ClientStAcquired block point query m a)
recvMsgAcquired} (SendMsgAcquired ServerStAcquired block point query m b
server') = do
      client' <- m (ClientStAcquired block point query m a)
recvMsgAcquired
      directAcquired client' server'
    directAcquiring ClientStAcquiring{AcquireFailure -> m (ClientStIdle block point query m a)
recvMsgFailure :: AcquireFailure -> m (ClientStIdle block point query m a)
recvMsgFailure :: forall block point (query :: * -> *) (m :: * -> *) a.
ClientStAcquiring block point query m a
-> AcquireFailure -> m (ClientStIdle block point query m a)
recvMsgFailure} (SendMsgFailure AcquireFailure
failure ServerStIdle block point query m b
server') = do
      client' <- AcquireFailure -> m (ClientStIdle block point query m a)
recvMsgFailure AcquireFailure
failure
      directIdle client' server'

    directAcquired
      :: ClientStAcquired block point query m a
      -> ServerStAcquired block point query m b
      -> m (a, b)
    directAcquired :: ClientStAcquired block point query m a
-> ServerStAcquired block point query m b -> m (a, b)
directAcquired (SendMsgQuery query result
query ClientStQuerying block point query m a result
client') ServerStAcquired{forall result.
query result -> m (ServerStQuerying block point query m b result)
recvMsgQuery :: forall result.
query result -> m (ServerStQuerying block point query m b result)
recvMsgQuery :: forall block point (query :: * -> *) (m :: * -> *) a.
ServerStAcquired block point query m a
-> forall result.
   query result -> m (ServerStQuerying block point query m a result)
recvMsgQuery} = do
      server' <- query result -> m (ServerStQuerying block point query m b result)
forall result.
query result -> m (ServerStQuerying block point query m b result)
recvMsgQuery query result
query
      directQuerying client' server'
    directAcquired (SendMsgReAcquire Target point
tgt ClientStAcquiring block point query m a
client') ServerStAcquired{Target point -> m (ServerStAcquiring block point query m b)
recvMsgReAcquire :: Target point -> m (ServerStAcquiring block point query m b)
recvMsgReAcquire :: forall block point (query :: * -> *) (m :: * -> *) a.
ServerStAcquired block point query m a
-> Target point -> m (ServerStAcquiring block point query m a)
recvMsgReAcquire} = do
      server' <- Target point -> m (ServerStAcquiring block point query m b)
recvMsgReAcquire Target point
tgt
      directAcquiring client' server'
    directAcquired (SendMsgRelease m (ClientStIdle block point query m a)
client) ServerStAcquired{m (ServerStIdle block point query m b)
recvMsgRelease :: m (ServerStIdle block point query m b)
recvMsgRelease :: forall block point (query :: * -> *) (m :: * -> *) a.
ServerStAcquired block point query m a
-> m (ServerStIdle block point query m a)
recvMsgRelease} = do
      client' <- m (ClientStIdle block point query m a)
client
      server' <- recvMsgRelease
      directIdle client' server'

    directQuerying
      :: ClientStQuerying block point query m a result
      -> ServerStQuerying block point query m b result
      -> m (a, b)
    directQuerying :: forall result.
ClientStQuerying block point query m a result
-> ServerStQuerying block point query m b result -> m (a, b)
directQuerying ClientStQuerying{result -> m (ClientStAcquired block point query m a)
recvMsgResult :: result -> m (ClientStAcquired block point query m a)
recvMsgResult :: forall block point (query :: * -> *) (m :: * -> *) a result.
ClientStQuerying block point query m a result
-> result -> m (ClientStAcquired block point query m a)
recvMsgResult} (SendMsgResult result
result ServerStAcquired block point query m b
server') = do
      client' <- result -> m (ClientStAcquired block point query m a)
recvMsgResult result
result
      directAcquired client' server'