{-# LANGUAGE AllowAmbiguousTypes #-}

module IHP.LoginSupport.Middleware (initAuthentication) where

import IHP.Prelude
import IHP.LoginSupport.Helper.Controller
import IHP.Controller.Session
import IHP.QueryBuilder
import IHP.Fetch
import IHP.ControllerSupport
import IHP.ModelSupport
import IHP.Controller.Context
import IHP.Hasql.FromRow (FromRowHasql)

{-# INLINE initAuthentication #-}
initAuthentication :: forall user normalizedModel.
        ( ?context :: ControllerContext
        , ?request :: Request
        , ?modelContext :: ModelContext
        , normalizedModel ~ NormalizeModel user
        , Typeable normalizedModel
        , Table normalizedModel
        , FromRowHasql normalizedModel
        , PrimaryKey (GetTableName normalizedModel) ~ UUID
        , GetTableName normalizedModel ~ GetTableName user
        , FilterPrimaryKey (GetTableName normalizedModel)
        , KnownSymbol (GetModelName user)
    ) => IO ()
initAuthentication :: forall user normalizedModel.
(?context::ControllerContext, ?request::Request,
 ?modelContext::ModelContext, normalizedModel ~ NormalizeModel user,
 Typeable normalizedModel, Table normalizedModel,
 FromRowHasql normalizedModel,
 PrimaryKey (GetTableName normalizedModel) ~ UUID,
 GetTableName normalizedModel ~ GetTableName user,
 FilterPrimaryKey (GetTableName normalizedModel),
 KnownSymbol (GetModelName user)) =>
IO ()
initAuthentication = do
    user <- forall value.
(?request::Request, Serialize value) =>
ByteString -> IO (Maybe value)
getSession @(Id user) (forall user. KnownSymbol (GetModelName user) => ByteString
sessionKey @user)
            IO (Maybe (Id' (GetTableName user)))
-> (Maybe (Id' (GetTableName user)) -> IO (Maybe normalizedModel))
-> IO (Maybe normalizedModel)
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe (Id' (GetTableName user)) -> IO (Maybe normalizedModel)
forall fetchable model.
(Fetchable fetchable model, Table model, FromRowHasql model,
 ?modelContext::ModelContext) =>
fetchable -> IO (Maybe model)
fetchOneOrNothing
    putContext user