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
        ]