content: {-# LANGUAGE NoImplicitPrelude #-}
  {-# LANGUAGE OverloadedStrings #-}
  {-# LANGUAGE TemplateHaskell #-}
  {-# LANGUAGE MultiParamTypeClasses #-}
  {-# LANGUAGE TypeFamilies #-}
  {-# LANGUAGE ViewPatterns #-}
  {-# LANGUAGE InstanceSigs #-}
  
  module Foundation where
  
  import Import.NoFoundation
  import Control.Monad.Logger (LogSource)
  
  import Yesod.Core.Types     (Logger)
  import qualified Yesod.Core.Unsafe as Unsafe
  
  -- | The foundation datatype for your application. This can be a good place to
  -- keep settings and values requiring initialization before your application
  -- starts running, such as database connections. Every handler will have
  -- access to the data present here.
  data App = App
      { appSettings    :: AppSettings
      , appStatic      :: Static -- ^ Settings for static file serving.
      , appHttpManager :: Manager
      , appLogger      :: Logger
      }
  
  -- This is where we define all of the routes in our application. For a full
  -- explanation of the syntax, please see:
  -- http://www.yesodweb.com/book/routing-and-handlers
  --
  -- Note that this is really half the story; in Application.hs, mkYesodDispatch
  -- generates the rest of the code. Please see the following documentation
  -- for an explanation for this split:
  -- http://www.yesodweb.com/book/scaffolding-and-the-site-template#scaffolding-and-the-site-template_foundation_and_application_modules
  --
  -- This function also generates the following type synonyms:
  -- type Handler = HandlerFor App
  -- type Widget = WidgetFor App ()
  mkYesodData "App" $(parseRoutesFile "config/routes.yesodroutes")
  
  -- Please see the documentation for the Yesod typeclass. There are a number
  -- of settings which can be configured by overriding methods here.
  instance Yesod App where
      -- Controls the base of generated URLs. For more information on modifying,
      -- see: https://github.com/yesodweb/yesod/wiki/Overriding-approot
      approot :: Approot App
      approot = ApprootRequest $ \app req ->
          case appRoot $ appSettings app of
              Nothing -> getApprootText guessApproot app req
              Just root -> root
  
      makeSessionBackend :: App -> IO (Maybe SessionBackend)
      makeSessionBackend _ = return Nothing
  
      -- Yesod Middleware allows you to run code before and after each handler function.
      -- The defaultYesodMiddleware adds the response header "Vary: Accept, Accept-Language" and performs authorization checks.
      -- Some users may also want to add the defaultCsrfMiddleware, which:
      --   a) Sets a cookie with a CSRF token in it.
      --   b) Validates that incoming write requests include that token in either a header or POST parameter.
      -- To add it, chain it together with the defaultMiddleware: yesodMiddleware = defaultYesodMiddleware . defaultCsrfMiddleware
      -- For details, see the CSRF documentation in the Yesod.Core.Handler module of the yesod-core package.
      yesodMiddleware :: ToTypedContent res => Handler res -> Handler res
      yesodMiddleware = defaultYesodMiddleware
  
      -- What messages should be logged. The following includes all messages when
      -- in development, and warnings and errors in production.
      shouldLogIO :: App -> LogSource -> LogLevel -> IO Bool
      shouldLogIO app _source level =
          return $
          appShouldLogAll (appSettings app)
              || level == LevelWarn
              || level == LevelError
  
      makeLogger :: App -> IO Logger
      makeLogger = return . appLogger
  
      errorHandler :: ErrorResponse -> Handler TypedContent
      errorHandler = defaultErrorHandlerJson
  
  -- Useful when writing code that is re-usable outside of the Handler context.
  -- An example is background jobs that send email.
  -- This can also be useful for writing code that works across multiple Yesod applications.
  instance HasHttpManager App where
      getHttpManager :: App -> Manager
      getHttpManager = appHttpManager
  
  unsafeHandler :: App -> Handler a -> IO a
  unsafeHandler = Unsafe.fakeHandlerGetLogger appLogger
  
  -- Note: Some functionality previously present in the scaffolding has been
  -- moved to documentation in the Wiki. Following are some hopefully helpful
  -- links:
  --
  -- https://github.com/yesodweb/yesod/wiki/Sending-email
  -- https://github.com/yesodweb/yesod/wiki/Serve-static-files-from-a-separate-domain
  -- https://github.com/yesodweb/yesod/wiki/i18n-messages-in-the-scaffolding
  