{-|
Module      : Invitations.hs
Description : GarganText Mailing Invitations
Copyright   : (c) CNRS, 2017-Present
License     : AGPL + CECILL v3
Maintainer  : team@gargantext.org
Stability   : experimental
Portability : POSIX


 -}

{-# LANGUAGE Strict            #-}

module CLI.Invitations where

import CLI.Parsers
import CLI.Types
import Gargantext.API.Admin.Settings
import Gargantext.API.Admin.Types
import Gargantext.API.Dev (withDevEnv, runCmdDev)
import Gargantext.API.Errors.Types
import Gargantext.API.Node () -- instances only
import Gargantext.API.Node.Share qualified as Share
import Gargantext.API.Node.Share.Types qualified as Share
import Gargantext.Core.AsyncUpdates.CentralExchange.Types qualified as CET
import Gargantext.Core.Config (readConfig)
import Gargantext.Core.NLP (HasNLPServer)
import Gargantext.Core.Types
import Gargantext.Core.Types.Individu (User(..))
import Gargantext.Database.Prelude (CmdRandom)
import Gargantext.Prelude
import Options.Applicative
import Prelude (String)

invitationsCLI :: InvitationsArgs -> IO ()
invitationsCLI (InvitationsArgs iniPath settingsPath user node_id email) = do
  _cfg       <- readConfig         (_IniFile iniPath)

  let invite :: ( HasSettings env
                , CmdRandom env BackendInternalError m
                , HasNLPServer env
                , CET.HasCentralExchangeNotification env ) => m Int
      invite = Share.api (UserName $ cs user) node_id (Share.ShareTeamParams $ cs email)

  withDevEnv iniPath settingsPath $ \env -> do
    void $ runCmdDev env invite

invitationsCmd :: HasCallStack => Mod CommandFields CLI
invitationsCmd = command "invitations" (info (helper <*> fmap CLISub invitations_p) (progDesc "Mailing invitations."))

invitations_p :: Parser CLICmd
invitations_p = fmap CCMD_invitations $ InvitationsArgs
  <$> ini_p
  <*> settings_p
  <*> ( strOption ( long "user" ) )
  <*> ( option (eitherReader node_p)  ( long "node-id" <> metavar "POSITIVE-INT" <> help "The node ID.") )
  <*> ( strOption ( long "email" <> help "The email address.") )

node_p :: String -> Either String NodeId
node_p i = case readMaybe i of
  Nothing -> Left $ i <> " is not a valid integer."
  Just xs
    | xs < 0 -> Left $ "The node id needs to be a positive integer."
    | otherwise
    -> Right $ UnsafeMkNodeId xs
