{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}

module Main where

import Control.Lens

{-- Snap --}
import Snap.Http.Server (defaultConfig)
import Snap.Util.FileServe (serveDirectory)

{-- Snaplets --}
import Snap.Snaplet
import Snap.Snaplet.Auth
import Snap.Snaplet.Auth.Backends.PostgresqlSimple
import Snap.Snaplet.Session
import Snap.Snaplet.Session.Backends.CookieSession
import Snap.Snaplet.PostgresqlSimple
import Snap.Snaplet.Heist

import Snap.Snaplet.JobBoard (JobBoard, jobBoardInit)

-- | We need all of these for the Job Board snaplet.
data App = App
  { _sess  :: Snaplet SessionManager
  , _db    :: Snaplet Postgres
  , _auth  :: Snaplet (AuthManager App)
  , _heist :: Snaplet (Heist App)
  , _board :: Snaplet (JobBoard App)
  }

makeLenses ''App

-- | This is needed so the JobBoard snaplet can use splices
instance HasHeist App where
  heistLens = subSnaplet heist

appInit :: SnapletInit App App
appInit = makeSnaplet "App" "App" Nothing $ do
  s <- nestSnaplet "" sess $
       initCookieSessionManager "site_key.txt" "_cookie" Nothing
  d <- nestSnaplet "db" db pgsInit
  a <- nestSnaplet "auth" auth $ initPostgresAuth sess d
  h <- nestSnaplet "" heist $ heistInit "templates"
  b <- nestSnaplet "" board $
    jobBoardInit auth (subSnaplet db) d

  -- Serve static files.
  addRoutes [("", serveDirectory "static")]
  return $ App s d a h b

main :: IO ()
main = serveSnaplet defaultConfig appInit
