module Jobs.Types
  ( Job(..), Notification(..)
  , JobCtl(..)
  , JobContext(..)
  ) where

import Import.NoFoundation

import Data.Aeson (defaultOptions, Options(..), SumEncoding(..))
import Data.Aeson.TH (deriveJSON)

import Data.List.NonEmpty (NonEmpty)


data Job = JobSendNotification { jRecipient :: UserId, jNotification :: Notification }
         | JobSendTestEmail { jEmail :: Email, jMailContext :: MailContext }
         | JobQueueNotification { jNotification :: Notification }
         | JobHelpRequest { jHelpSender :: Either (Maybe Address) UserId
                          , jRequestTime :: UTCTime
                          , jSubject :: Maybe Text
                          , jHelpRequest :: Text
                          , jReferer :: Maybe Text
                          }
         | JobSetLogSettings { jInstance :: InstanceId, jLogSettings :: LogSettings }
         | JobDistributeCorrections { jSheet :: SheetId }
         | JobSendCourseCommunication { jRecipientEmail :: Either UserEmail UserId
                                      , jAllRecipientAddresses :: Set Address
                                      , jCourse :: CourseId
                                      , jSender :: UserId
                                      , jMailObjectUUID :: UUID
                                      , jSubject :: Maybe Text
                                      , jMailContent :: Html
                                      }
         | JobLecturerInvitation { jInviter :: UserId
                                 , jLecturerInvitation :: LecturerInvitation
                                 }
         | JobCorrectorInvitation { jInviter :: UserId
                                  , jCorrectorInvitation :: SheetCorrectorInvitation
                                  }
  deriving (Eq, Ord, Show, Read, Generic, Typeable)
data Notification = NotificationSubmissionRated { nSubmission :: SubmissionId }
                  | NotificationSheetActive { nSheet :: SheetId }
                  | NotificationSheetSoonInactive { nSheet :: SheetId }
                  | NotificationSheetInactive { nSheet :: SheetId }
                  | NotificationCorrectionsAssigned { nUser :: UserId, nSheet :: SheetId }
                  | NotificationCorrectionsNotDistributed { nSheet :: SheetId }
                  | NotificationUserRightsUpdate { nUser :: UserId, originalRights :: [(SchoolShorthand,Bool,Bool)] } -- User rights (admin, lecturer,...) were changed somehow
  deriving (Eq, Ord, Show, Read, Generic, Typeable)

instance Hashable Job
instance Hashable Notification

deriveJSON defaultOptions
  { constructorTagModifier = camelToPathPiece' 1
  , fieldLabelModifier = camelToPathPiece' 1
  , tagSingleConstructors = True
  , sumEncoding = TaggedObject "job" "data"
  } ''Job

deriveJSON defaultOptions
  { constructorTagModifier = camelToPathPiece' 1
  , fieldLabelModifier = camelToPathPiece' 1
  , tagSingleConstructors = True
  , sumEncoding = TaggedObject "notification" "data"
  } ''Notification


data JobCtl = JobCtlFlush
            | JobCtlPerform QueuedJobId
            | JobCtlDetermineCrontab
            | JobCtlQueue Job
  deriving (Eq, Ord, Read, Show, Generic, Typeable)

instance Hashable JobCtl


data JobContext = JobContext
  { jobCrontab :: TMVar (Crontab JobCtl)
  , jobConfirm :: TVar (HashMap JobCtl (NonEmpty (TMVar (Maybe SomeException))))
  }
