module Jobs.Handler.PruneFiles
  ( dispatchJobPruneSessionFiles
  , dispatchJobPruneUnreferencedFiles
  ) where

import Import hiding (matching)

import Database.Persist.Sql (deleteWhereCount)

import qualified Database.Esqueleto as E
import qualified Database.Esqueleto.Utils as E


dispatchJobPruneSessionFiles :: Handler ()
dispatchJobPruneSessionFiles = do
  now <- liftIO getCurrentTime
  expires <- getsYesod $ view _appSessionFilesExpire
  n <- runDB $ deleteWhereCount [ SessionFileTouched <. addUTCTime (- expires) now ]
  $logInfoS "PruneSessionFiles" [st|Deleted #{n} expired session files|]


dispatchJobPruneUnreferencedFiles :: Handler ()
dispatchJobPruneUnreferencedFiles = do
  n <- runDB . E.deleteCount . E.from $ \file ->
    E.where_ . E.not_ . E.any E.exists $ references file
  $logInfoS "PruneUnreferencedFiles" [st|Deleted #{n} unreferenced files|]
  where
    references :: E.SqlExpr (Entity File) -> [E.SqlQuery ()]
    references ((E.^. FileId) -> fId) =
      [ E.from $ \matching  -> E.where_ $ matching  E.^. AllocationMatchingLog        E.==. fId
      , E.from $ \appInstr  -> E.where_ $ appInstr  E.^. CourseAppInstructionFileFile E.==. fId
      , E.from $ \appFile   -> E.where_ $ appFile   E.^. CourseApplicationFileFile    E.==. fId
      , E.from $ \matFile   -> E.where_ $ matFile   E.^. MaterialFileFile             E.==. fId
      , E.from $ \newsFile  -> E.where_ $ newsFile  E.^. CourseNewsFileFile           E.==. fId
      , E.from $ \sessFile  -> E.where_ $ sessFile  E.^. SessionFileFile              E.==. fId
      , E.from $ \sheetFile -> E.where_ $ sheetFile E.^. SheetFileFile                E.==. fId
      , E.from $ \subFile   -> E.where_ $ subFile   E.^. SubmissionFileFile           E.==. fId
      ]
