{-# LANGUAGE TemplateHaskell #-}
module Gargantext.API.Admin.Settings.TOML where

import Control.Lens hiding ((.=))
import Data.Text qualified as T
import Gargantext.API.Admin.Settings.CORS
import Gargantext.API.Admin.Settings.MicroServices
import Gargantext.Prelude (panicTrace)
import Gargantext.System.Logging
import Prelude
import Toml
import Servant.Client.Core.BaseUrl

-- | Compatibility bridge until we fix #304 (move to Toml)
data GargTomlSettings = GargTomlSettings
  { _gargCorsSettings          :: !CORSSettings
  , _gargMicroServicesSettings :: !MicroServicesSettings
  }

makeLenses ''GargTomlSettings

settingsCodec :: TomlCodec GargTomlSettings
settingsCodec = GargTomlSettings
  <$> (Toml.table corsSettingsCodec "cors" .= _gargCorsSettings)
  <*> (Toml.table  microServicesSettingsCodec "microservices.proxy" .= _gargMicroServicesSettings)

-- | Extends the 'allowed-origins' in the CORSettings with the URLs embellished
-- with the proxy port.
addProxyToAllowedOrigins :: GargTomlSettings -> GargTomlSettings
addProxyToAllowedOrigins stgs =
  stgs & over gargCorsSettings (addProxies $ stgs ^. gargMicroServicesSettings . msProxyPort)
  where
    addProxies :: Int -> CORSSettings -> CORSSettings
    addProxies port cors =
      let origins = _corsAllowedOrigins cors
          mkUrl (CORSOrigin u) = case parseBaseUrl (T.unpack u) of
            Nothing -> CORSOrigin u
            Just bh -> CORSOrigin $ T.pack $ showBaseUrl $ bh { baseUrlPort = port }
      in cors { _corsAllowedOrigins = origins <> Prelude.map mkUrl origins }

-- | Loads the 'CORSSettings' from the 'toml' file.
loadGargTomlSettings :: FilePath -> IO GargTomlSettings
loadGargTomlSettings tomlFile = do
  tomlRes <- Toml.decodeFileEither settingsCodec tomlFile
  case tomlRes of
      Left errs      -> do
        withLogger () $ \ioLogger -> do
          logMsg ioLogger ERROR $ T.unpack $ "Error, gargantext-settings.toml parsing failed: " <> Toml.prettyTomlDecodeErrors errs
          panicTrace "Please fix the errors in your gargantext-settings.toml file."
      Right settings0 -> case settings0 ^. gargCorsSettings . corsUseOriginsForHosts of
        True  -> pure $ addProxyToAllowedOrigins $ settings0 & over (gargCorsSettings . corsAllowedHosts) (\_ -> "http://localhost:3000" : (settings0 ^. gargCorsSettings . corsAllowedOrigins))
        False -> pure $ addProxyToAllowedOrigins $ settings0 & over (gargCorsSettings . corsAllowedHosts) ("http://localhost:3000" :)
