module Main where import Data.Aeson qualified as A import Network.Wai.Handler.Warp (run, Port) import Network.Wai.Middleware.RequestLogger qualified as Logger import System.Environment (getArgs) import System.Environment (lookupEnv) import Web.Twain qualified as Twain import Fedi qualified as Fedi import Data.Functor ((<&>)) main :: IO () main = do getArgs >>= \case [] -> pure () _ -> usageError fediPort <- maybe 3001 read <$> lookupEnv "FEDI_PORT" runServer fediPort =<< mkFediApp usageError :: err usageError = errorWithoutStackTrace $ unlines [ "Usage: fedi" , "Env vars:" , " - FEDI_PORT=" , " - FEDI_DETAILS=" ] -- | Run server at at specific port. runServer :: Port -> Twain.Application -> IO () runServer port app = do putStrLn $ unwords [ "Running fedi at" , "http://localhost:" <> show port , "(ctrl-c to quit)" ] run port (Logger.logStdoutDev app) -- | Application description. mkFediApp :: IO Twain.Application mkFediApp = do detailsFile <- lookupEnv "FEDI_DETAILS" <&> maybe (error "missing FEDI_DETAILS") id details <- A.decodeFileStrict detailsFile <&> maybe (error $ "could not read file '" <> detailsFile <> "'.") id pure $ foldr ($) (Twain.notFound $ Twain.send $ Twain.text "Error: not found.") (Fedi.routes details)