content: {-# LANGUAGE TemplateHaskell #-}
  
  module Unused.ResultsClassifier.Config
      ( loadConfig
      , loadAllConfigurations
      ) where
  
  import qualified Data.Bifunctor as BF
  import qualified Data.ByteString as BS
  import qualified Data.Either as E
  import qualified Data.FileEmbed as FE
  import qualified Data.Yaml as Y
  import qualified System.Directory as D
  import System.FilePath ((</>))
  import Unused.ResultsClassifier.Types (LanguageConfiguration, ParseConfigError(..))
  import Unused.Util (safeReadFile)
  
  loadConfig :: Either String [LanguageConfiguration]
  loadConfig = decodeEither defaultConfigFile
  
  defaultConfigFile :: BS.ByteString
  defaultConfigFile = $(FE.embedFile "data/config.yml")
  
  loadAllConfigurations :: IO (Either [ParseConfigError] [LanguageConfiguration])
  loadAllConfigurations = do
      homeDir <- D.getHomeDirectory
      let defaultConfig = addSourceToLeft "default config" loadConfig
      localConfig <- loadConfigFromFile ".unused.yml"
      userConfig <- loadConfigFromFile $ homeDir </> ".unused.yml"
      let (lefts, rights) = E.partitionEithers [defaultConfig, localConfig, userConfig]
      return $
          if not (null lefts)
              then Left lefts
              else Right $ concat rights
  
  loadConfigFromFile :: String -> IO (Either ParseConfigError [LanguageConfiguration])
  loadConfigFromFile path =
      either (const $ Right []) (addSourceToLeft path . decodeEither) <$> safeReadFile path
  
  addSourceToLeft :: String -> Either String c -> Either ParseConfigError c
  addSourceToLeft = BF.first . ParseConfigError
  
  decodeEither :: Y.FromJSON a => BS.ByteString -> Either String a
  decodeEither = BF.first Y.prettyPrintParseException . Y.decodeEither'
  