{-# LANGUAGE RankNTypes #-}

module Web.Spock.Internal.Config where

import qualified Data.Text as T
import qualified Data.Text.IO as T
import Data.Word
import Network.HTTP.Types.Status
import System.IO
import Web.Spock.Internal.CoreAction
import Web.Spock.Logging
import Web.Routing.SafeRouting (SlashPolicy (..))
import qualified Web.Spock.Internal.Wire as W

data SpockConfig = SpockConfig
  { -- | Maximum request body size in bytes, checked as an action reads the
    -- body (including JSON, form parameters, and uploads). An unused body is
    -- not read or rejected based on its declared length. Exceeding the limit
    -- invokes 'sc_errorHandler' with status 413.
    SpockConfig -> Maybe Word64
sc_maxRequestSize :: Maybe Word64,
    -- | Error handler. Given status is set in response by default, but you
    -- can always override it with `setStatus`
    SpockConfig -> Status -> ActionCtxT () IO ()
sc_errorHandler :: Status -> W.ActionCtxT () IO (),
    -- | Function that should be called to log errors.
    SpockConfig -> Text -> IO ()
sc_logError :: T.Text -> IO (),
    -- | Optional request IDs and structured handler/access/error events.
    SpockConfig -> Maybe LoggingConfig
sc_logging :: Maybe LoggingConfig,
    -- | Empty-segment matching. 'IgnoreSlashes' retains historical behavior.
    -- 'StrictSlashes' distinguishes @/foo@ and @/foo/@. 'RedirectTrailingSlashes'
    -- uses strict matching, then sends 308 if changing only the final slash
    -- finds a route for the same method. A matching wildcard or fallback wins.
    SpockConfig -> SlashPolicy
sc_slashPolicy :: SlashPolicy
  }

-- | Default Spock configuration. No restriction on maximum request size; error
-- handler simply prints status message as plain text and all errors are logged
-- to stderr.
defaultSpockConfig :: SpockConfig
defaultSpockConfig :: SpockConfig
defaultSpockConfig = Maybe Word64
-> (Status -> ActionCtxT () IO ())
-> (Text -> IO ())
-> Maybe LoggingConfig
-> SlashPolicy
-> SpockConfig
SpockConfig Maybe Word64
forall a. Maybe a
Nothing Status -> ActionCtxT () IO ()
forall {ctx} {a}. Status -> ActionCtxT ctx IO a
defaultHandler (Handle -> Text -> IO ()
T.hPutStrLn Handle
stderr) Maybe LoggingConfig
forall a. Maybe a
Nothing SlashPolicy
IgnoreSlashes
  where
    defaultHandler :: Status -> ActionCtxT ctx IO a
defaultHandler = ByteString -> ActionCtxT ctx IO a
forall (m :: * -> *) ctx a.
MonadIO m =>
ByteString -> ActionCtxT ctx m a
bytes (ByteString -> ActionCtxT ctx IO a)
-> (Status -> ByteString) -> Status -> ActionCtxT ctx IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Status -> ByteString
statusMessage