    -- |
    -- Module      : Network.TLS.Struct13
    -- License     : BSD-style
    -- Maintainer  : Vincent Hanquez <vincent@snarc.org>
    -- Stability   : experimental
    -- Portability : unknown
    --
    module Network.TLS.Struct13
           ( Packet13(..)
           , Handshake13(..)
           , HandshakeType13(..)
           , typeOfHandshake13
           , contentType
           , KeyUpdate(..)
           ) where

    import Data.X509 (CertificateChain)
    import Network.TLS.Struct
    import Network.TLS.Types
    import Network.TLS.Imports

    data Packet13 =
          Handshake13 [Handshake13]
        | Alert13 [(AlertLevel, AlertDescription)]
        | ChangeCipherSpec13
        | AppData13 ByteString
        deriving (Int -> Packet13 -> ShowS
    [Packet13] -> ShowS
    Packet13 -> String
    (Int -> Packet13 -> ShowS)
    -> (Packet13 -> String) -> ([Packet13] -> ShowS) -> Show Packet13
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [Packet13] -> ShowS
    $cshowList :: [Packet13] -> ShowS
    show :: Packet13 -> String
    $cshow :: Packet13 -> String
    showsPrec :: Int -> Packet13 -> ShowS
    $cshowsPrec :: Int -> Packet13 -> ShowS
    Show,Packet13 -> Packet13 -> Bool
    (Packet13 -> Packet13 -> Bool)
    -> (Packet13 -> Packet13 -> Bool) -> Eq Packet13
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: Packet13 -> Packet13 -> Bool
    $c/= :: Packet13 -> Packet13 -> Bool
    == :: Packet13 -> Packet13 -> Bool
    $c== :: Packet13 -> Packet13 -> Bool
    Eq)

    data KeyUpdate = UpdateNotRequested
                   | UpdateRequested
                   deriving (Int -> KeyUpdate -> ShowS
    [KeyUpdate] -> ShowS
    KeyUpdate -> String
    (Int -> KeyUpdate -> ShowS)
    -> (KeyUpdate -> String)
    -> ([KeyUpdate] -> ShowS)
    -> Show KeyUpdate
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [KeyUpdate] -> ShowS
    $cshowList :: [KeyUpdate] -> ShowS
    show :: KeyUpdate -> String
    $cshow :: KeyUpdate -> String
    showsPrec :: Int -> KeyUpdate -> ShowS
    $cshowsPrec :: Int -> KeyUpdate -> ShowS
    Show,KeyUpdate -> KeyUpdate -> Bool
    (KeyUpdate -> KeyUpdate -> Bool)
    -> (KeyUpdate -> KeyUpdate -> Bool) -> Eq KeyUpdate
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: KeyUpdate -> KeyUpdate -> Bool
    $c/= :: KeyUpdate -> KeyUpdate -> Bool
    == :: KeyUpdate -> KeyUpdate -> Bool
    $c== :: KeyUpdate -> KeyUpdate -> Bool
    Eq)

    type TicketNonce = ByteString

    -- fixme: convert Word32 to proper data type
    data Handshake13 =
          ClientHello13 !Version !ClientRandom !Session ![CipherID] [ExtensionRaw]
        | ServerHello13 !ServerRandom !Session !CipherID [ExtensionRaw]
        | NewSessionTicket13 Second Word32 TicketNonce SessionID [ExtensionRaw]
        | EndOfEarlyData13
        | EncryptedExtensions13 [ExtensionRaw]
        | CertRequest13 CertReqContext [ExtensionRaw]
        | Certificate13 CertReqContext CertificateChain [[ExtensionRaw]]
        | CertVerify13 HashAndSignatureAlgorithm Signature
        | Finished13 FinishedData
        | KeyUpdate13 KeyUpdate
        deriving (Int -> Handshake13 -> ShowS
    [Handshake13] -> ShowS
    Handshake13 -> String
    (Int -> Handshake13 -> ShowS)
    -> (Handshake13 -> String)
    -> ([Handshake13] -> ShowS)
    -> Show Handshake13
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [Handshake13] -> ShowS
    $cshowList :: [Handshake13] -> ShowS
    show :: Handshake13 -> String
    $cshow :: Handshake13 -> String
    showsPrec :: Int -> Handshake13 -> ShowS
    $cshowsPrec :: Int -> Handshake13 -> ShowS
    Show,Handshake13 -> Handshake13 -> Bool
    (Handshake13 -> Handshake13 -> Bool)
    -> (Handshake13 -> Handshake13 -> Bool) -> Eq Handshake13
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: Handshake13 -> Handshake13 -> Bool
    $c/= :: Handshake13 -> Handshake13 -> Bool
    == :: Handshake13 -> Handshake13 -> Bool
    $c== :: Handshake13 -> Handshake13 -> Bool
    Eq)

    data HandshakeType13 =
          HandshakeType_ClientHello13
        | HandshakeType_ServerHello13
        | HandshakeType_EndOfEarlyData13
        | HandshakeType_NewSessionTicket13
        | HandshakeType_EncryptedExtensions13
        | HandshakeType_CertRequest13
        | HandshakeType_Certificate13
        | HandshakeType_CertVerify13
        | HandshakeType_Finished13
        | HandshakeType_KeyUpdate13
        deriving (Int -> HandshakeType13 -> ShowS
    [HandshakeType13] -> ShowS
    HandshakeType13 -> String
    (Int -> HandshakeType13 -> ShowS)
    -> (HandshakeType13 -> String)
    -> ([HandshakeType13] -> ShowS)
    -> Show HandshakeType13
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [HandshakeType13] -> ShowS
    $cshowList :: [HandshakeType13] -> ShowS
    show :: HandshakeType13 -> String
    $cshow :: HandshakeType13 -> String
    showsPrec :: Int -> HandshakeType13 -> ShowS
    $cshowsPrec :: Int -> HandshakeType13 -> ShowS
    Show,HandshakeType13 -> HandshakeType13 -> Bool
    (HandshakeType13 -> HandshakeType13 -> Bool)
    -> (HandshakeType13 -> HandshakeType13 -> Bool)
    -> Eq HandshakeType13
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: HandshakeType13 -> HandshakeType13 -> Bool
    $c/= :: HandshakeType13 -> HandshakeType13 -> Bool
    == :: HandshakeType13 -> HandshakeType13 -> Bool
    $c== :: HandshakeType13 -> HandshakeType13 -> Bool
    Eq)

    typeOfHandshake13 :: Handshake13 -> HandshakeType13
    typeOfHandshake13 :: Handshake13 -> HandshakeType13
    typeOfHandshake13 ClientHello13{}         = HandshakeType13
    HandshakeType_ClientHello13
    typeOfHandshake13 ServerHello13{}         = HandshakeType13
    HandshakeType_ServerHello13
    typeOfHandshake13 EndOfEarlyData13{}      = HandshakeType13
    HandshakeType_EndOfEarlyData13
    typeOfHandshake13 NewSessionTicket13{}    = HandshakeType13
    HandshakeType_NewSessionTicket13
    typeOfHandshake13 EncryptedExtensions13{} = HandshakeType13
    HandshakeType_EncryptedExtensions13
    typeOfHandshake13 CertRequest13{}         = HandshakeType13
    HandshakeType_CertRequest13
    typeOfHandshake13 Certificate13{}         = HandshakeType13
    HandshakeType_Certificate13
    typeOfHandshake13 CertVerify13{}          = HandshakeType13
    HandshakeType_CertVerify13
    typeOfHandshake13 Finished13{}            = HandshakeType13
    HandshakeType_Finished13
    typeOfHandshake13 KeyUpdate13{}           = HandshakeType13
    HandshakeType_KeyUpdate13

    instance TypeValuable HandshakeType13 where
      valOfType :: HandshakeType13 -> Word8
    valOfType HandshakeType_ClientHello13         = 1
      valOfType HandshakeType_ServerHello13         = 2
      valOfType HandshakeType_NewSessionTicket13    = 4
      valOfType HandshakeType_EndOfEarlyData13      = 5
      valOfType HandshakeType_EncryptedExtensions13 = 8
      valOfType HandshakeType_CertRequest13         = 13
      valOfType HandshakeType_Certificate13         = 11
      valOfType HandshakeType_CertVerify13          = 15
      valOfType HandshakeType_Finished13            = 20
      valOfType HandshakeType_KeyUpdate13           = 24

      valToType :: Word8 -> Maybe HandshakeType13
    valToType 1  = HandshakeType13 -> Maybe HandshakeType13
    forall a. a -> Maybe a
    Just HandshakeType13
    HandshakeType_ClientHello13
      valToType 2  = HandshakeType13 -> Maybe HandshakeType13
    forall a. a -> Maybe a
    Just HandshakeType13
    HandshakeType_ServerHello13
      valToType 4  = HandshakeType13 -> Maybe HandshakeType13
    forall a. a -> Maybe a
    Just HandshakeType13
    HandshakeType_NewSessionTicket13
      valToType 5  = HandshakeType13 -> Maybe HandshakeType13
    forall a. a -> Maybe a
    Just HandshakeType13
    HandshakeType_EndOfEarlyData13
      valToType 8  = HandshakeType13 -> Maybe HandshakeType13
    forall a. a -> Maybe a
    Just HandshakeType13
    HandshakeType_EncryptedExtensions13
      valToType 13 = HandshakeType13 -> Maybe HandshakeType13
    forall a. a -> Maybe a
    Just HandshakeType13
    HandshakeType_CertRequest13
      valToType 11 = HandshakeType13 -> Maybe HandshakeType13
    forall a. a -> Maybe a
    Just HandshakeType13
    HandshakeType_Certificate13
      valToType 15 = HandshakeType13 -> Maybe HandshakeType13
    forall a. a -> Maybe a
    Just HandshakeType13
    HandshakeType_CertVerify13
      valToType 20 = HandshakeType13 -> Maybe HandshakeType13
    forall a. a -> Maybe a
    Just HandshakeType13
    HandshakeType_Finished13
      valToType 24 = HandshakeType13 -> Maybe HandshakeType13
    forall a. a -> Maybe a
    Just HandshakeType13
    HandshakeType_KeyUpdate13
      valToType _  = Maybe HandshakeType13
    forall a. Maybe a
    Nothing

    contentType :: Packet13 -> ProtocolType
    contentType :: Packet13 -> ProtocolType
    contentType ChangeCipherSpec13 = ProtocolType
    ProtocolType_ChangeCipherSpec
    contentType (Handshake13 _)    = ProtocolType
    ProtocolType_Handshake
    contentType (Alert13 _)        = ProtocolType
    ProtocolType_Alert
    contentType (AppData13 _)      = ProtocolType
    ProtocolType_AppData