-- SPDX-FileCopyrightText: 2022-23 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <vaupel.sarah@campus.lmu.de>,Steffen Jost <s.jost@fraport.de>
--
-- SPDX-License-Identifier: AGPL-3.0-or-later

module Audit.Types
  ( Transaction(..)
  ) where

import ClassyPrelude.Yesod hiding (derivePersistFieldJSON)
import Model.Types.TH.JSON
import Model

import Data.Aeson.TH
import Utils.PathPiece


data Transaction
  = TransactionTermEdit
    { transactionTerm   :: TermId
    }

  | TransactionExamRegister
    { transactionExam   :: ExamId
    , transactionUser   :: UserId
    }
  | TransactionExamDeregister
    { transactionExam   :: ExamId
    , transactionUser   :: UserId
    }

  | TransactionExamPartResultEdit
    { transactionExamPart :: ExamPartId
    , transactionUser     :: UserId
    }
  | TransactionExamPartResultDeleted
    { transactionExamPart :: ExamPartId
    , transactionUser     :: UserId
    }

  | TransactionExamBonusEdit
    { transactionExam   :: ExamId
    , transactionUser   :: UserId
    }
  | TransactionExamBonusDeleted
    { transactionExam   :: ExamId
    , transactionUser   :: UserId
    }

  | TransactionExamResultEdit
    { transactionExam   :: ExamId
    , transactionUser   :: UserId
    }
  | TransactionExamResultDeleted
    { transactionExam   :: ExamId
    , transactionUser   :: UserId
    }

  | TransactionCourseParticipantEdit
    { transactionCourse :: CourseId
    , transactionUser   :: UserId
    }
  | TransactionCourseParticipantDeleted
    { transactionCourse :: CourseId
    , transactionUser   :: UserId
    }

  | TransactionSubmissionEdit
    { transactionSubmission :: SubmissionId
    , transactionSheet      :: SheetId
    }
  | TransactionSubmissionDelete
    { transactionSubmission :: SubmissionId
    , transactionSheet      :: SheetId
    }

  | TransactionSubmissionUserEdit
    { transactionSubmission :: SubmissionId
    , transactionUser       :: UserId
    }
  | TransactionSubmissionUserDelete
    { transactionSubmission :: SubmissionId
    , transactionUser       :: UserId
    }

  | TransactionSubmissionFileEdit
    { transactionSubmissionFile :: Entity SubmissionFile
    }
  | TransactionSubmissionFileDelete
    { transactionSubmissionFile :: Entity SubmissionFile
    }

  | TransactionExamOfficeUserAdd
    { transactionOffice :: UserId
    , transactionUser :: UserId
    }
  | TransactionExamOfficeUserDelete
    { transactionOffice :: UserId
    , transactionUser :: UserId
    }
  | TransactionExamOfficeFieldEdit
    { transactionOffice :: UserId
    , transactionField :: StudyTermsId
    }
  | TransactionExamOfficeFieldDelete
    { transactionOffice :: UserId
    , transactionField :: StudyTermsId
    }
  | TransactionTutorialEdit
    { transactionTutorial :: TutorialId
    }
  | TransactionTutorialDelete
    { transactionTutorial :: TutorialId
    }

  | TransactionTutorialParticipantEdit
    { transactionTutorial            :: TutorialId
    , transactionTutorialParticipant :: TutorialParticipantId
    , transactionUser                :: UserId
    }
  | TransactionTutorialParticipantDelete
    { transactionTutorial            :: TutorialId
    , transactionTutorialParticipant :: TutorialParticipantId
    , transactionUser                :: UserId
    }

  | TransactionExternalExamEdit
    { transactionExternalExam :: ExternalExamId
    }

  | TransactionExternalExamOfficeSchoolEdit
    { transactionExternalExam :: ExternalExamId
    , transactionSchool       :: SchoolId
    }
  | TransactionExternalExamOfficeSchoolDelete
    { transactionExternalExam :: ExternalExamId
    , transactionSchool       :: SchoolId
    }

  | TransactionExternalExamStaffEdit
    { transactionExternalExam :: ExternalExamId
    , transactionUser         :: UserId
    }
  | TransactionExternalExamStaffDelete
    { transactionExternalExam :: ExternalExamId
    , transactionUser         :: UserId
    }
  | TransactionExternalExamStaffInviteEdit
    { transactionExternalExam :: ExternalExamId
    , transactionEmail        :: UserEmail
    }
  | TransactionExternalExamStaffInviteDelete
    { transactionExternalExam :: ExternalExamId
    , transactionEmail        :: UserEmail
    }

  | TransactionExternalExamResultEdit
    { transactionExternalExam :: ExternalExamId
    , transactionUser         :: UserId
    }
  | TransactionExternalExamResultDelete
    { transactionExternalExam :: ExternalExamId
    , transactionUser         :: UserId
    }

  | TransactionSubmissionGroupSet
    { transactionCourse       :: CourseId
    , transactionUser         :: UserId
    , transactionSubmissionGroup :: SubmissionGroupName
    }
  | TransactionSubmissionGroupUnset
    { transactionCourse       :: CourseId
    , transactionUser         :: UserId
    }

  | TransactionUserAssimilated
    { transactionUser
    , transactionAssimilatedUser :: UserId
    }
  | TransactionUserIdentChanged
    { transactionOldUserIdent
    , transactionNewUserIdent    :: UserIdent
    }
  | TransactionLmsStart
    { transactionQualification :: QualificationId
    , transactionLmsIdent      :: LmsIdent    
    , transactionLmsUser       :: UserId
    , transactionLmsUserKey    :: LmsUserId
    }
  | TransactionLmsReset
    { transactionQualification    :: QualificationId
    , transactionLmsUser          :: UserId
    , transactionLmsReset         :: Bool
    , transactionLmsResetExtend   :: Maybe Integer
    , transactionLmsResetUnblock  :: Maybe Bool
    , transactionLmsResetNotify   :: Maybe Bool
    }
  | TransactionLmsBlocked
    { transactionQualification :: QualificationId
    , transactionLmsIdent      :: LmsIdent
    , transactionLmsDay        :: UTCTime
    , transactionLmsUser       :: UserId
    , transactionNote          :: Maybe Text
    , transactionReceived      :: UTCTime -- when was the csv file received?
    }
  | TransactionLmsSuccess
    { transactionQualification :: QualificationId
    , transactionLmsIdent      :: LmsIdent
    , transactionLmsDay        :: UTCTime
    , transactionLmsUser       :: UserId
    , transactionNote          :: Maybe Text
    , transactionReceived      :: UTCTime -- when was the csv file received?
    }
  | TransactionQualificationUserEdit  -- Note that a renewal always entails unblocking as well!
    { transactionUser                         :: UserId                 -- qualification holder that is updated
    , transactionQualificationUser            :: QualificationUserId    -- not really necessary, maybe remove?
    , transactionQualification                :: QualificationId    
    , transactionQualificationValidUntil      :: Day
    , transactionQualificationScheduleRenewal :: Maybe Bool -- Maybe, because some update may leave it unchanged (also avoids DB Migration)
    , transactionNote                         :: Maybe Text
    }
  | TransactionQualificationUserDelete
    { transactionUser               :: UserId
    , transactionQualificationUser  :: QualificationUserId
    , transactionQualification      :: QualificationId
    }
  | TransactionQualificationUserBlocking
    { transactionUser               :: UserId                         -- qualification holder that is updated
      -- , transactionQualificationUser  :: QualificationUserId       -- not neccessary due to UniqueQualificationUser
    , transactionQualification      :: QualificationId
    , transactionQualificationBlock :: QualificationUserBlock         -- full information about block
    }
  | TransactionQualificationUserScheduleRenewal
    { transactionUser                         :: UserId               -- qualification holder that is updated
    , transactionQualification                :: QualificationId
    , transactionQualificationScheduleRenewal :: Maybe Bool           -- TRUE=will be notified upon expiry, FALSE=won't be notified; always JUST, for compatibility with TransactionQualificationUserEdit
    }
  | TransactionInterface
    { transactionInterfaceName                :: Text
    , transactionInterfaceSubtype             :: Text
    , transactionInterfaceWrite               :: Bool                 -- True implies a write to FRADrive
    , transactionInterfaceRows                :: Maybe Int
    , transactionInterfaceInfo                :: Text
    , transactionInterfaceSuccess             :: Maybe Bool            -- Just False implies a failure; Maybe used to achieve backwards compatibility
    }
  deriving (Eq, Ord, Read, Show, Generic)

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

derivePersistFieldJSON ''Transaction