{-# language BangPatterns #-}
{-# language NamedFieldPuns #-}
{-# language DataKinds #-}
{-# language DeriveFunctor #-}
{-# language DuplicateRecordFields #-}
{-# language FlexibleContexts #-}
{-# language GeneralizedNewtypeDeriving #-}
{-# language MultiParamTypeClasses #-}
{-# language OverloadedStrings #-}
{-# language PolyKinds #-}
{-# language RankNTypes #-}
{-# language TypeFamilies #-}
{-# language UnboxedTuples #-}
{-# language UndecidableInstances #-}

module Kafka.InitProducerId.Request.V4
  ( Request(..)
  , toChunks
    -- * Construction
  , request
  ) where

import Prelude hiding (id)

import Data.Int (Int16,Int32,Int64)
import Data.Text (Text)
import Data.Bytes.Builder (Builder)
import Data.Bytes.Chunks (Chunks)
import Data.WideWord (Word128)
import Data.Primitive (SmallArray)

import qualified Kafka.Builder as Builder

-- | An empty request. Everything in this request is set to something that
-- means "this is not being provided to the broker". This is the most common
-- value of this type to use. Note that transactionTimeoutMilliseconds is set
-- to 2147483647 because this is what the kafka-console-producer does.
request :: Request
request :: Request
request = Request
  { $sel:transactionalId:Request :: Maybe Text
transactionalId = Maybe Text
forall a. Maybe a
Nothing
  , $sel:transactionTimeoutMilliseconds:Request :: Int32
transactionTimeoutMilliseconds = Int32
2147483647
  , $sel:producerId:Request :: Int64
producerId = (-Int64
1)
  , $sel:producerEpoch:Request :: Int16
producerEpoch = (-Int16
1)
  }

-- | Kafka Init Producer ID request V4.
data Request = Request
  { Request -> Maybe Text
transactionalId :: !(Maybe Text)
    -- ^ The transactional id, or null if the producer is not transactional.
  , Request -> Int32
transactionTimeoutMilliseconds :: !Int32
    -- ^ The time in ms to wait before aborting idle transactions sent by this producer.
    -- This is only relevant if a TransactionalId has been defined.
  , Request -> Int64
producerId :: !Int64
    -- ^ The producer id. This is used to disambiguate requests if a transactional id
    -- is reused following its expiration. Typically, this should be set to -1.
  , Request -> Int16
producerEpoch :: !Int16
    -- ^ The producer's current epoch. This will be checked against the producer epoch
    -- on the broker, and the request will return an error if they do not match.
    -- Setting this to -1 disables this check, which is typically what you want.
  }

toChunks :: Request -> Chunks
toChunks :: Request -> Chunks
toChunks = Int -> Builder -> Chunks
Builder.run Int
128 (Builder -> Chunks) -> (Request -> Builder) -> Request -> Chunks
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Request -> Builder
encode

encode :: Request -> Builder
encode :: Request -> Builder
encode Request{Maybe Text
$sel:transactionalId:Request :: Request -> Maybe Text
transactionalId :: Maybe Text
transactionalId,Int32
$sel:transactionTimeoutMilliseconds:Request :: Request -> Int32
transactionTimeoutMilliseconds :: Int32
transactionTimeoutMilliseconds,Int64
$sel:producerId:Request :: Request -> Int64
producerId :: Int64
producerId,Int16
$sel:producerEpoch:Request :: Request -> Int16
producerEpoch :: Int16
producerEpoch} =
  Maybe Text -> Builder
Builder.compactNullableString Maybe Text
transactionalId
  Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<>
  Int32 -> Builder
Builder.int32 Int32
transactionTimeoutMilliseconds
  Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<>
  Int64 -> Builder
Builder.int64 Int64
producerId
  Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<>
  Int16 -> Builder
Builder.int16 Int16
producerEpoch
  Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<>
  Word8 -> Builder
Builder.word8 Word8
0