{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
module Network.HTTP2.Server.Types where
import Control.Concurrent.STM
import Control.Exception (SomeException)
import Data.ByteString.Builder (Builder)
import Data.IORef
import Data.IntMap.Strict (IntMap)
import Imports
import Network.HPACK
import Network.HTTP2
import Network.HTTP2.Priority
import Network.HTTP2.Server.API
data OpenState =
    JustOpened
  | Continued [HeaderBlockFragment]
              !Int  
              !Int  
              !Bool 
              !Priority
  | NoBody HeaderTable !Priority
  | HasBody HeaderTable !Priority
  | Body !(TQueue ByteString)
         !(Maybe Int) 
                      
         !(IORef Int) 
         !(IORef (Maybe HeaderTable)) 
data ClosedCode = Finished
                | Killed
                | Reset !ErrorCodeId
                | ResetByMe SomeException
                deriving Show
data StreamState =
    Idle
  | Open !OpenState
  | HalfClosedRemote
  | HalfClosedLocal !ClosedCode
  | Closed !ClosedCode
  | Reserved
instance Show StreamState where
    show Idle        = "Idle"
    show Open{}      = "Open"
    show HalfClosedRemote  = "HalfClosedRemote"
    show (HalfClosedLocal e)  = "HalfClosedLocal: " ++ show e
    show (Closed e)  = "Closed: " ++ show e
    show Reserved    = "Reserved"
data Stream = Stream {
    streamNumber     :: !StreamId
  , streamState      :: !(IORef StreamState)
  , streamWindow     :: !(TVar WindowSize)
  , streamPrecedence :: !(IORef Precedence)
  }
instance Show Stream where
  show s = show (streamNumber s)
newtype StreamTable = StreamTable (IORef (IntMap Stream))
data Input = Input Stream Request
data Output = Output {
    outputStream   :: Stream
  , outputResponse :: Response
  , outputType     :: OutputType
  , outputStrmQ    :: Maybe (TBQueue RspStreaming)
  , outputSentinel :: IO ()
  }
data OutputType = ORspn
                | OWait (IO ())
                | OPush !TokenHeaderList !StreamId 
                | ONext !DynaNext !TrailersMaker
type DynaNext = Buffer -> BufferSize -> WindowSize -> IO Next
type BytesFilled = Int
data Next = Next !BytesFilled (Maybe DynaNext)
data Control = CFinish
             | CGoaway    !ByteString
             | CFrame     !ByteString
             | CSettings  !ByteString !SettingsList
             | CSettings0 !ByteString !ByteString !SettingsList
data RspStreaming = RSFinish
                  | RSFlush
                  | RSBuilder Builder