module ServantSerf.Module where

import qualified Data.List as List
import qualified Data.Maybe as Maybe
import qualified ServantSerf.Type.Config as Config
import qualified ServantSerf.Type.Context as Context
import qualified ServantSerf.Type.ModuleName as ModuleName
import qualified System.FilePath as FilePath

generate :: Context.Context -> [FilePath] -> String
generate :: Context -> [String] -> String
generate Context
context [String]
files =
  let
    source :: String
source = Context -> String
Context.source Context
context
    config :: Config
config = Context -> Config
Context.config Context
context
    apiName :: String
apiName = Config -> String
Config.apiName Config
config
    serverName :: String
serverName = Config -> String
Config.serverName Config
config
    moduleName :: String
moduleName = case Config -> Maybe ModuleName
Config.moduleName Config
config of
      Maybe ModuleName
Nothing ->
        forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
"Main" ModuleName -> String
ModuleName.toString
          forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Maybe ModuleName
ModuleName.fromFilePath
          forall a b. (a -> b) -> a -> b
$ Context -> String
Context.source Context
context
      Just ModuleName
x -> ModuleName -> String
ModuleName.toString ModuleName
x
    suffix :: String
suffix = Config -> String
Config.excludeSuffix Config
config
    moduleNames :: [String]
moduleNames =
      (if forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
suffix then forall a. a -> a
id else forall a. (a -> Bool) -> [a] -> [a]
filter forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Eq a => [a] -> [a] -> Bool
List.isSuffixOf String
suffix)
        forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ModuleName -> String
ModuleName.toString
        forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Ord a => [a] -> [a]
List.sort
        forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> Maybe b) -> [a] -> [b]
Maybe.mapMaybe String -> Maybe ModuleName
ModuleName.fromFilePath
        forall a b. (a -> b) -> a -> b
$ forall a. (a -> Bool) -> [a] -> [a]
filter (String -> String -> Bool
FilePath.isExtensionOf String
"hs") [String]
files
  in [String] -> String
unlines
    [ String
"{-# LINE 1 " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show String
source forall a. Semigroup a => a -> a -> a
<> String
" #-}"
    , String
"{-# OPTIONS_GHC -w #-}"
    , String
""
    , String
"module " forall a. Semigroup a => a -> a -> a
<> String
moduleName forall a. Semigroup a => a -> a -> a
<> String
" where"
    , String
""
    , String
"import qualified Servant"
    , String
""
    , forall a. [a] -> [[a]] -> [a]
List.intercalate String
"\n" forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (String
"import qualified " forall a. Semigroup a => a -> a -> a
<>) [String]
moduleNames
    , String
""
    , String
"type " forall a. Semigroup a => a -> a -> a
<> String
apiName
    , String
"\t= " forall a. Semigroup a => a -> a -> a
<> if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
moduleNames
      then String
"Servant.EmptyAPI"
      else forall a. [a] -> [[a]] -> [a]
List.intercalate String
"\n\tServant.:<|> "
        forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. Semigroup a => a -> a -> a
<> String
"." forall a. Semigroup a => a -> a -> a
<> String
apiName) [String]
moduleNames
    , String
""
    , String
serverName
    , String
"\t= " forall a. Semigroup a => a -> a -> a
<> if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
moduleNames
      then String
"Servant.emptyServer"
      else forall a. [a] -> [[a]] -> [a]
List.intercalate String
"\n\tServant.:<|> "
        forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. Semigroup a => a -> a -> a
<> String
"." forall a. Semigroup a => a -> a -> a
<> String
serverName) [String]
moduleNames
    ]