module Main (main) where

import Core
import Database
import Handlers
import Logger
import Routes

import Control.Monad.Except     (ExceptT (ExceptT))
import Data.List
import Effectful
import Effectful.Error.Static   (Error, runErrorNoCallStack, throwError)
import Effectful.FileSystem
import Effectful.Reader.Static
import Network.Wai.Handler.Warp (run)
import Servant hiding           ((:>), throwError)
import qualified Servant        as S

--
-- Application
--
main :: IO ()
main = do
  pool <- createConnectionPool
  let env = AppEnv { pool = pool }
  run port $ serve proxy $ app env

app :: AppEnv -> Server AppAPI
app env = transformEff env
        $ rootHandler
     :<|> userListHandler
     :<|> userGetHandler
     :<|> userPostHandler
     :<|> userDeleteHandler

transformEff :: AppEnv -> ServerT AppAPI AppEff -> ServerT AppAPI Handler
transformEff env = hoistServer proxy
  $ Handler
  . ExceptT
  . runEff
  . runErrorNoCallStack
  . runReader env
  . runDatabaseIO
  . runLoggerPSQL
  . runFileSystem

port :: Int
port = 8080

proxy :: Proxy AppAPI
proxy = Proxy