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

-}


module CLI.Server where

import Data.Version (showVersion)
import CLI.Parsers (settings_p)
import CLI.Types
import CLI.Worker (runAllWorkers)
import GHC.IO.Encoding (setLocaleEncoding, utf8)
import Gargantext.API (startGargantext)
import Gargantext.API.Admin.EnvTypes (Mode(..))
import Gargantext.Core.Config.Types (_SettingsFile)
import Gargantext.Prelude
import Gargantext.System.Logging (withLogger, logMsg, LogLevel(..), Logger)
import Options.Applicative
import Paths_gargantext qualified as PG -- cabal magic build module



serverCLI :: CLIServer -> IO ()
serverCLI (CLIS_start serverArgs) = withLogger () $ \ioLogger ->
  startServerCLI ioLogger serverArgs

serverCLI (CLIS_startAll serverArgs@(ServerArgs { .. })) = withLogger () $ \ioLogger -> do
  withAsync (startServerCLI ioLogger serverArgs) $ \aServer -> do
    runAllWorkers ioLogger server_toml
    wait aServer

serverCLI (CLIS_version) = withLogger () $ \ioLogger -> do
    -- Sets the locale to avoid encoding issues like in #284.
  setLocaleEncoding utf8
  logMsg ioLogger INFO $ "Version: " <> showVersion PG.version


serverCmd :: HasCallStack => Mod CommandFields CLI
serverCmd = command "server" (info (helper <*> (fmap CLISub $ fmap CCMD_server serverParser))
                               (progDesc "Gargantext server."))

serverParser :: Parser CLIServer
serverParser = hsubparser (
  command "start" (info (helper <*> start_p)
                      (progDesc "Start the server")) <>
  command "start-all" (info (helper <*> start_all_p)
                        (progDesc "Start the server and all workers (forked)")) <>
  command "version" (info (helper <*> version_p)
                      (progDesc "Show version and exit"))
  )

start_p :: Parser CLIServer
start_p = fmap CLIS_start $ ServerArgs
  <$> mode_p 
  <*> port_p
  <*> settings_p

start_all_p :: Parser CLIServer
start_all_p = fmap CLIS_startAll $ ServerArgs
  <$> mode_p 
  <*> port_p
  <*> settings_p

mode_p :: Parser Mode
mode_p = option auto ( long "mode"
                    <> short 'm'
                    <> metavar "M"
                    <> help "Possible modes: Dev | Mock | Prod" )

port_p :: Parser Int
port_p = option auto ( long "port"
                    <> short 'p'
                    <> metavar "P"
                    <> showDefault
                    <> value 8008
                    <> help "Port" )
  
version_p :: Parser CLIServer
version_p = pure CLIS_version


startServerCLI :: Logger IO -> ServerArgs -> IO ()
startServerCLI ioLogger (ServerArgs { .. }) = do
  logMsg ioLogger INFO $ "starting server, mode: " <> show server_mode <> ", port: " <> show server_port <> ", config: " <> _SettingsFile server_toml
  -- Sets the locale to avoid encoding issues like in #284.
  setLocaleEncoding utf8

  when (server_mode == Mock) $ do
    logMsg ioLogger ERROR "Mock mode not supported!"
    exitFailure

  startGargantext server_mode server_port server_toml