-- | Load a 'JUnitConfig' using environment variables
module Test.Hspec.JUnit.Config.Env
    ( envJUnitEnabled
    , envJUnitConfig
    ) where

import Prelude

import Data.Semigroup (Endo(..))
import Data.Text (pack)
import System.Directory (getCurrentDirectory)
import System.Environment (lookupEnv)
import System.FilePath (takeBaseName)
import Test.Hspec.JUnit.Config

-- | Is @JUNIT_ENABLED=1@ set in the environment?
envJUnitEnabled :: IO Bool
envJUnitEnabled :: IO Bool
envJUnitEnabled = (Maybe String -> Maybe String -> Bool
forall a. Eq a => a -> a -> Bool
== String -> Maybe String
forall a. a -> Maybe a
Just String
"1") (Maybe String -> Bool) -> IO (Maybe String) -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO (Maybe String)
lookupEnv (String
envPrefix String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"ENABLED")

-- | Produce a 'JUnitConfig' by reading environment variables
--
-- Variable names align with setter functions from "Test.Hspec.JUnit.Config":
--
-- * @JUNIT_OUTPUT_DIRECTORY@ 'setJUnitConfigOutputDirectory'
-- * @JUNIT_OUTPUT_NAME@ 'setJUnitConfigOutputName
-- * and so on
--
envJUnitConfig :: IO JUnitConfig
envJUnitConfig :: IO JUnitConfig
envJUnitConfig = do
  JUnitConfig -> JUnitConfig
modify <- Endo JUnitConfig -> JUnitConfig -> JUnitConfig
forall a. Endo a -> a -> a
appEndo (Endo JUnitConfig -> JUnitConfig -> JUnitConfig)
-> ([JUnitConfig -> JUnitConfig] -> Endo JUnitConfig)
-> [JUnitConfig -> JUnitConfig]
-> JUnitConfig
-> JUnitConfig
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((JUnitConfig -> JUnitConfig) -> Endo JUnitConfig)
-> [JUnitConfig -> JUnitConfig] -> Endo JUnitConfig
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (JUnitConfig -> JUnitConfig) -> Endo JUnitConfig
forall a. (a -> a) -> Endo a
Endo ([JUnitConfig -> JUnitConfig] -> JUnitConfig -> JUnitConfig)
-> IO [JUnitConfig -> JUnitConfig]
-> IO (JUnitConfig -> JUnitConfig)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [IO (JUnitConfig -> JUnitConfig)]
-> IO [JUnitConfig -> JUnitConfig]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence
    [ String
-> (String -> JUnitConfig -> JUnitConfig)
-> IO (JUnitConfig -> JUnitConfig)
lookupEnvOverride String
"OUTPUT_DIRECTORY" String -> JUnitConfig -> JUnitConfig
setJUnitConfigOutputDirectory
    , String
-> (String -> JUnitConfig -> JUnitConfig)
-> IO (JUnitConfig -> JUnitConfig)
lookupEnvOverride String
"OUTPUT_NAME" String -> JUnitConfig -> JUnitConfig
setJUnitConfigOutputName
    , String
-> (String -> JUnitConfig -> JUnitConfig)
-> IO (JUnitConfig -> JUnitConfig)
lookupEnvOverride String
"OUTPUT_FILE" String -> JUnitConfig -> JUnitConfig
setJUnitConfigOutputFile
    , String
-> (String -> JUnitConfig -> JUnitConfig)
-> IO (JUnitConfig -> JUnitConfig)
lookupEnvOverride String
"SUITE_NAME" ((String -> JUnitConfig -> JUnitConfig)
 -> IO (JUnitConfig -> JUnitConfig))
-> (String -> JUnitConfig -> JUnitConfig)
-> IO (JUnitConfig -> JUnitConfig)
forall a b. (a -> b) -> a -> b
$ Text -> JUnitConfig -> JUnitConfig
setJUnitConfigSuiteName (Text -> JUnitConfig -> JUnitConfig)
-> (String -> Text) -> String -> JUnitConfig -> JUnitConfig
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
pack
    , String
-> (String -> JUnitConfig -> JUnitConfig)
-> IO (JUnitConfig -> JUnitConfig)
lookupEnvOverride String
"SOURCE_PATH_PREFIX" String -> JUnitConfig -> JUnitConfig
setJUnitConfigSourcePathPrefix
    ]

  JUnitConfig -> JUnitConfig
modify (JUnitConfig -> JUnitConfig)
-> (String -> JUnitConfig) -> String -> JUnitConfig
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> JUnitConfig
defaultJUnitConfig (Text -> JUnitConfig) -> (String -> Text) -> String -> JUnitConfig
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
pack (String -> Text) -> (String -> String) -> String -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
takeBaseName (String -> JUnitConfig) -> IO String -> IO JUnitConfig
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO String
getCurrentDirectory

lookupEnvOverride
  :: String
  -> (String -> JUnitConfig -> JUnitConfig)
  -> IO (JUnitConfig -> JUnitConfig)
lookupEnvOverride :: String
-> (String -> JUnitConfig -> JUnitConfig)
-> IO (JUnitConfig -> JUnitConfig)
lookupEnvOverride String
name String -> JUnitConfig -> JUnitConfig
setter =
  (JUnitConfig -> JUnitConfig)
-> (String -> JUnitConfig -> JUnitConfig)
-> Maybe String
-> JUnitConfig
-> JUnitConfig
forall b a. b -> (a -> b) -> Maybe a -> b
maybe JUnitConfig -> JUnitConfig
forall a. a -> a
id String -> JUnitConfig -> JUnitConfig
setter (Maybe String -> JUnitConfig -> JUnitConfig)
-> IO (Maybe String) -> IO (JUnitConfig -> JUnitConfig)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO (Maybe String)
lookupEnv (String
envPrefix String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
name)

envPrefix :: String
envPrefix :: String
envPrefix = String
"JUNIT_"