{--| Support in Gargantext for CORS (Cross-origin resource sharing) --}

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

import Prelude

import Control.Arrow
import Data.Text qualified as T
import Toml
import Control.Lens hiding (iso, (.=))
import Servant.Client.Core
import Data.Maybe (fromMaybe)

newtype CORSOrigin = CORSOrigin { _CORSOrigin :: BaseUrl }
  deriving (Show, Eq)

data CORSSettings =
  CORSSettings {
    _corsAllowedOrigins :: [CORSOrigin]
  , _corsAllowedHosts   :: [CORSOrigin]
  -- | If 'True', we will reuse the origin whitelist
  -- as the allowed hosts as well. This allows, for example,
  -- to connect from \"demo.gargantext.org\" to \"dev.sub.gargantext.org\"
  -- and vice-versa.
  , _corsUseOriginsForHosts :: !Bool
  } deriving (Show, Eq)

corsOriginCodec :: TomlBiMap CORSOrigin AnyValue
corsOriginCodec = _Orig >>> _Text
  where
   _Orig :: BiMap e CORSOrigin T.Text
   _Orig = iso (T.pack . showBaseUrl . _CORSOrigin)
               (\(T.unpack -> u) -> CORSOrigin . fromMaybe (error $ "invalid origin: " <> u) . parseBaseUrl $ u)

corsSettingsCodec :: TomlCodec CORSSettings
corsSettingsCodec = CORSSettings
     <$> Toml.arrayOf corsOriginCodec "allowed-origins" .= _corsAllowedOrigins
     <*> pure mempty -- FIXME(adn) Currently we don't need to support this field.
     <*> Toml.bool "use-origins-for-hosts" .= _corsUseOriginsForHosts

makeLenses ''CORSSettings
