{-# LANGUAGE TemplateHaskell #-}
{-|
Module      : Gargantext.Core.Worker.Jobs
Description : Worker job definitions
Copyright   : (c) CNRS, 2024
License     : AGPL + CECILL v3
Maintainer  : team@gargantext.org
Stability   : experimental
Portability : POSIX

-}


module Gargantext.Core.Worker.Jobs where


import Async.Worker qualified as W
import Control.Lens (view)
import Gargantext.Core.Config (gc_database_config, gc_worker, HasConfig(..), GargConfig, gc_logging)
import Gargantext.Core.Config.Worker (WorkerSettings(..), WorkerDefinition(..))
import Gargantext.Core.Worker.Broker (initBrokerWithDBCreate)
import Gargantext.Core.Worker.Jobs.Types (Job(..))
import Gargantext.Core.Worker.PGMQTypes (HasWorkerBroker, MessageId, SendJob)
import Gargantext.Database.Prelude (Cmd)
import Gargantext.Prelude
import Gargantext.System.Logging


sendJob :: (HasWorkerBroker, HasConfig env)
        => Job
        -> Cmd env err MessageId
sendJob job = do
  gcConfig <- view $ hasConfig
  liftBase $ sendJobWithCfg gcConfig job

sendJobWithCfg :: GargConfig -> Job -> IO MessageId
sendJobWithCfg gcConfig job = do
  let ws@WorkerSettings { _wsDefinitions, _wsDefaultDelay } = gcConfig ^. gc_worker
  -- TODO Try to guess which worker should get this job
  -- let mWd = findDefinitionByName ws workerName
  let mWd = head _wsDefinitions
  case mWd of
    Nothing -> panicTrace "No worker definitions available"
    Just wd -> do
      b <- initBrokerWithDBCreate (gcConfig ^. gc_database_config) ws
      let queueName = _wdQueue wd
      let job' = (updateJobData job $ W.mkDefaultSendJob' b queueName job) { W.delay = _wsDefaultDelay }
      withLogger (gcConfig ^. gc_logging) $ \ioL ->
        $(logLoc) ioL DEBUG $ "[sendJob] sending job " <> show job <> " (delay " <> show (W.delay job') <> ")"
      W.sendJob' job'

-- | We want to fine-tune job metadata parameters, for each job type
updateJobData :: Job -> SendJob -> SendJob
updateJobData (AddCorpusWithQuery {}) sj = sj { W.timeout = 3000 }
updateJobData (AddToAnnuaireWithForm {}) sj = sj { W.timeout = 3000 }
updateJobData (AddWithFile {}) sj = sj { W.timeout = 3000 }
updateJobData (DocumentsFromWriteNodes {}) sj = sj { W.timeout = 3000 }
updateJobData (FrameCalcUpload {}) sj = sj { W.timeout = 3000 }
updateJobData (JSONPost {}) sj = sj { W.timeout = 3000 }
updateJobData (NgramsPostCharts {}) sj = sj { W.timeout = 3000 }
updateJobData (RecomputeGraph {}) sj = sj { W.timeout = 3000 }
updateJobData (UpdateNode {}) sj = sj { W.timeout = 3000 }
updateJobData (UploadDocument {}) sj = sj { W.timeout = 3000 }
updateJobData (ImportRemoteDocuments {}) sj = sj { W.timeout = 3000 }
updateJobData (ImportRemoteTerms {}) sj = sj { W.timeout = 3000 }
-- | ForgotPasswordAsync, PostNodeAsync
updateJobData _ sj = sj { W.resendOnKill = False
                        , W.timeout = 60 }
