{-# LANGUAGE RecordWildCards #-}

module Network.QUIC.Stream.Types (
    Stream(..)
  , newStream
  , TxStreamData(..)
  , Flow(..)
  , defaultFlow
  , flowWindow
  , StreamState(..)
  , RecvStreamQ(..)
  , RxStreamData(..)
  , Length
  ) where

import Control.Concurrent.STM
import qualified Data.ByteString as BS

import {-# Source #-} Network.QUIC.Connection.Types
import Network.QUIC.Imports
import Network.QUIC.Stream.Frag
import Network.QUIC.Stream.Skew
import qualified Network.QUIC.Stream.Skew as Skew
import Network.QUIC.Types

----------------------------------------------------------------

-- | An abstract data type for streams.
data Stream = Stream {
    Stream -> StreamId
streamId         :: StreamId -- ^ Getting stream identifier.
  , Stream -> Connection
streamConnection :: Connection
  -- "counter" is equivalent to "offset".
  -- It is duplicated but used for API level flow control.
  , Stream -> TVar Flow
streamFlowTx     :: TVar  Flow        -- counter, maxDax
  , Stream -> IORef Flow
streamFlowRx     :: IORef Flow        -- counter, maxDax
  , Stream -> IORef StreamState
streamStateTx    :: IORef StreamState -- offset, fin
  , Stream -> IORef StreamState
streamStateRx    :: IORef StreamState -- offset, fin
  , Stream -> RecvStreamQ
streamRecvQ      :: RecvStreamQ       -- input bytestring
  , Stream -> IORef (Skew RxStreamData)
streamReass      :: IORef (Skew RxStreamData) -- input stream fragments to streamQ
  }

instance Show Stream where
    show :: Stream -> String
show Stream
s = StreamId -> String
forall a. Show a => a -> String
show (StreamId -> String) -> StreamId -> String
forall a b. (a -> b) -> a -> b
$ Stream -> StreamId
streamId Stream
s

newStream :: Connection -> StreamId -> IO Stream
newStream :: Connection -> StreamId -> IO Stream
newStream Connection
conn StreamId
sid = StreamId
-> Connection
-> TVar Flow
-> IORef Flow
-> IORef StreamState
-> IORef StreamState
-> RecvStreamQ
-> IORef (Skew RxStreamData)
-> Stream
Stream StreamId
sid Connection
conn (TVar Flow
 -> IORef Flow
 -> IORef StreamState
 -> IORef StreamState
 -> RecvStreamQ
 -> IORef (Skew RxStreamData)
 -> Stream)
-> IO (TVar Flow)
-> IO
     (IORef Flow
      -> IORef StreamState
      -> IORef StreamState
      -> RecvStreamQ
      -> IORef (Skew RxStreamData)
      -> Stream)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Flow -> IO (TVar Flow)
forall a. a -> IO (TVar a)
newTVarIO Flow
defaultFlow
                                     IO
  (IORef Flow
   -> IORef StreamState
   -> IORef StreamState
   -> RecvStreamQ
   -> IORef (Skew RxStreamData)
   -> Stream)
-> IO (IORef Flow)
-> IO
     (IORef StreamState
      -> IORef StreamState
      -> RecvStreamQ
      -> IORef (Skew RxStreamData)
      -> Stream)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Flow -> IO (IORef Flow)
forall a. a -> IO (IORef a)
newIORef  Flow
defaultFlow
                                     IO
  (IORef StreamState
   -> IORef StreamState
   -> RecvStreamQ
   -> IORef (Skew RxStreamData)
   -> Stream)
-> IO (IORef StreamState)
-> IO
     (IORef StreamState
      -> RecvStreamQ -> IORef (Skew RxStreamData) -> Stream)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StreamState -> IO (IORef StreamState)
forall a. a -> IO (IORef a)
newIORef  StreamState
emptyStreamState
                                     IO
  (IORef StreamState
   -> RecvStreamQ -> IORef (Skew RxStreamData) -> Stream)
-> IO (IORef StreamState)
-> IO (RecvStreamQ -> IORef (Skew RxStreamData) -> Stream)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> StreamState -> IO (IORef StreamState)
forall a. a -> IO (IORef a)
newIORef  StreamState
emptyStreamState
                                     IO (RecvStreamQ -> IORef (Skew RxStreamData) -> Stream)
-> IO RecvStreamQ -> IO (IORef (Skew RxStreamData) -> Stream)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> IO RecvStreamQ
newRecvStreamQ
                                     IO (IORef (Skew RxStreamData) -> Stream)
-> IO (IORef (Skew RxStreamData)) -> IO Stream
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Skew RxStreamData -> IO (IORef (Skew RxStreamData))
forall a. a -> IO (IORef a)
newIORef Skew RxStreamData
forall a. Skew a
Skew.empty

----------------------------------------------------------------

type Length = Int

data TxStreamData = TxStreamData Stream [StreamData] Length Fin

data RxStreamData = RxStreamData {
    RxStreamData -> StreamData
rxstrmData :: StreamData
  , RxStreamData -> StreamId
rxstrmOff  :: Offset
  , RxStreamData -> StreamId
rxstrmLen  :: Length
  , RxStreamData -> Fin
rxstrmFin  :: Fin
  } deriving (RxStreamData -> RxStreamData -> Fin
(RxStreamData -> RxStreamData -> Fin)
-> (RxStreamData -> RxStreamData -> Fin) -> Eq RxStreamData
forall a. (a -> a -> Fin) -> (a -> a -> Fin) -> Eq a
/= :: RxStreamData -> RxStreamData -> Fin
$c/= :: RxStreamData -> RxStreamData -> Fin
== :: RxStreamData -> RxStreamData -> Fin
$c== :: RxStreamData -> RxStreamData -> Fin
Eq, StreamId -> RxStreamData -> ShowS
[RxStreamData] -> ShowS
RxStreamData -> String
(StreamId -> RxStreamData -> ShowS)
-> (RxStreamData -> String)
-> ([RxStreamData] -> ShowS)
-> Show RxStreamData
forall a.
(StreamId -> a -> ShowS)
-> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RxStreamData] -> ShowS
$cshowList :: [RxStreamData] -> ShowS
show :: RxStreamData -> String
$cshow :: RxStreamData -> String
showsPrec :: StreamId -> RxStreamData -> ShowS
$cshowsPrec :: StreamId -> RxStreamData -> ShowS
Show)

instance Frag RxStreamData where
    currOff :: RxStreamData -> StreamId
currOff RxStreamData
r = RxStreamData -> StreamId
rxstrmOff RxStreamData
r
    nextOff :: RxStreamData -> StreamId
nextOff RxStreamData
r = RxStreamData -> StreamId
rxstrmOff RxStreamData
r StreamId -> StreamId -> StreamId
forall a. Num a => a -> a -> a
+ RxStreamData -> StreamId
rxstrmLen RxStreamData
r
    shrink :: StreamId -> RxStreamData -> RxStreamData
shrink StreamId
off'  (RxStreamData StreamData
bs StreamId
off StreamId
len Fin
fin) =
        let n :: StreamId
n = StreamId
off' StreamId -> StreamId -> StreamId
forall a. Num a => a -> a -> a
- StreamId
off
            bs' :: StreamData
bs'  = StreamId -> StreamData -> StreamData
BS.drop StreamId
n StreamData
bs
            len' :: StreamId
len' = StreamId
len StreamId -> StreamId -> StreamId
forall a. Num a => a -> a -> a
- StreamId
n
        in StreamData -> StreamId -> StreamId -> Fin -> RxStreamData
RxStreamData StreamData
bs' StreamId
off' StreamId
len' Fin
fin

----------------------------------------------------------------

data Flow = Flow {
    Flow -> StreamId
flowData :: Int
  , Flow -> StreamId
flowMaxData :: Int
  } deriving (Flow -> Flow -> Fin
(Flow -> Flow -> Fin) -> (Flow -> Flow -> Fin) -> Eq Flow
forall a. (a -> a -> Fin) -> (a -> a -> Fin) -> Eq a
/= :: Flow -> Flow -> Fin
$c/= :: Flow -> Flow -> Fin
== :: Flow -> Flow -> Fin
$c== :: Flow -> Flow -> Fin
Eq, StreamId -> Flow -> ShowS
[Flow] -> ShowS
Flow -> String
(StreamId -> Flow -> ShowS)
-> (Flow -> String) -> ([Flow] -> ShowS) -> Show Flow
forall a.
(StreamId -> a -> ShowS)
-> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Flow] -> ShowS
$cshowList :: [Flow] -> ShowS
show :: Flow -> String
$cshow :: Flow -> String
showsPrec :: StreamId -> Flow -> ShowS
$cshowsPrec :: StreamId -> Flow -> ShowS
Show)

defaultFlow :: Flow
defaultFlow :: Flow
defaultFlow = StreamId -> StreamId -> Flow
Flow StreamId
0 StreamId
0

flowWindow :: Flow -> Int
flowWindow :: Flow -> StreamId
flowWindow Flow{StreamId
flowMaxData :: StreamId
flowData :: StreamId
flowMaxData :: Flow -> StreamId
flowData :: Flow -> StreamId
..} = StreamId
flowMaxData StreamId -> StreamId -> StreamId
forall a. Num a => a -> a -> a
- StreamId
flowData

----------------------------------------------------------------

data StreamState = StreamState {
    StreamState -> StreamId
streamOffset :: Offset
  , StreamState -> Fin
streamFin :: Fin
  } deriving (StreamState -> StreamState -> Fin
(StreamState -> StreamState -> Fin)
-> (StreamState -> StreamState -> Fin) -> Eq StreamState
forall a. (a -> a -> Fin) -> (a -> a -> Fin) -> Eq a
/= :: StreamState -> StreamState -> Fin
$c/= :: StreamState -> StreamState -> Fin
== :: StreamState -> StreamState -> Fin
$c== :: StreamState -> StreamState -> Fin
Eq, StreamId -> StreamState -> ShowS
[StreamState] -> ShowS
StreamState -> String
(StreamId -> StreamState -> ShowS)
-> (StreamState -> String)
-> ([StreamState] -> ShowS)
-> Show StreamState
forall a.
(StreamId -> a -> ShowS)
-> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [StreamState] -> ShowS
$cshowList :: [StreamState] -> ShowS
show :: StreamState -> String
$cshow :: StreamState -> String
showsPrec :: StreamId -> StreamState -> ShowS
$cshowsPrec :: StreamId -> StreamState -> ShowS
Show)

emptyStreamState :: StreamState
emptyStreamState :: StreamState
emptyStreamState = StreamId -> Fin -> StreamState
StreamState StreamId
0 Fin
False

----------------------------------------------------------------

data RecvStreamQ = RecvStreamQ {
    RecvStreamQ -> TQueue StreamData
recvStreamQ :: TQueue ByteString
  , RecvStreamQ -> IORef (Maybe StreamData)
pendingData :: IORef (Maybe ByteString)
  , RecvStreamQ -> IORef Fin
endOfStream :: IORef Bool
  }

newRecvStreamQ :: IO RecvStreamQ
newRecvStreamQ :: IO RecvStreamQ
newRecvStreamQ = TQueue StreamData
-> IORef (Maybe StreamData) -> IORef Fin -> RecvStreamQ
RecvStreamQ (TQueue StreamData
 -> IORef (Maybe StreamData) -> IORef Fin -> RecvStreamQ)
-> IO (TQueue StreamData)
-> IO (IORef (Maybe StreamData) -> IORef Fin -> RecvStreamQ)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO (TQueue StreamData)
forall a. IO (TQueue a)
newTQueueIO IO (IORef (Maybe StreamData) -> IORef Fin -> RecvStreamQ)
-> IO (IORef (Maybe StreamData)) -> IO (IORef Fin -> RecvStreamQ)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe StreamData -> IO (IORef (Maybe StreamData))
forall a. a -> IO (IORef a)
newIORef Maybe StreamData
forall a. Maybe a
Nothing IO (IORef Fin -> RecvStreamQ) -> IO (IORef Fin) -> IO RecvStreamQ
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Fin -> IO (IORef Fin)
forall a. a -> IO (IORef a)
newIORef Fin
False