module Handler.Submission
  ( getSubmissionOwnR
  , module Handler.Submission.New
  , module Handler.Submission.Show
  , module Handler.Submission.Download
  , module Handler.Submission.Delete
  , module Handler.Submission.Assign
  , module Handler.Submission.SubmissionUserInvite
  , module Handler.Submission.List
  , module Handler.Submission.Correction
  , module Handler.Submission.Create
  , module Handler.Submission.Grade
  , module Handler.Submission.Upload
  , module Handler.Submission.AuthorshipStatements
  ) where

import Handler.Submission.New
import Handler.Submission.Show
import Handler.Submission.Download
import Handler.Submission.Delete
import Handler.Submission.Assign
import Handler.Submission.SubmissionUserInvite (getSInviteR, postSInviteR)
import Handler.Submission.List (getCorrectionsR, postCorrectionsR, getCCorrectionsR, postCCorrectionsR, getSSubsR, postSSubsR)
import Handler.Submission.Correction
import Handler.Submission.Create
import Handler.Submission.Grade
import Handler.Submission.Upload
import Handler.Submission.AuthorshipStatements

import Handler.Utils


import Import

import qualified Database.Esqueleto.Legacy as E


getSubmissionOwnR :: TermId -> SchoolId -> CourseShorthand -> SheetName -> Handler Html
-- For security reasons (unauthorized users not being allowed to have
-- guesses about which sheets/courses exist confirmed) this handlers
-- behaviour may not allow users to distinguish between:
--   - course does not exist (answers 404)
--   - course exists but sheet does not (answers 404)
--   - course and sheet exist but user has no submission (answers 404)
--   - course and sheet exist, user has submission, but is not
--     authorized to know course/sheet/submission exists (impossible,
--     because @!ownerANDread@ is sufficient for access to `SubShowR`;
--     having access to `SubShowR` allows user to determine
--     course/sheet from url)
getSubmissionOwnR tid ssh csh shn = do
  authId <- requireAuthId
  sid <- runDB . maybeT notFound $ do
    submissions <- lift . E.select . E.from $ \(course `E.InnerJoin` sheet `E.InnerJoin` submission `E.InnerJoin` submissionUser) -> do
      E.on $ submission E.^. SubmissionId E.==. submissionUser E.^. SubmissionUserSubmission
      E.on $ sheet E.^. SheetId E.==. submission E.^. SubmissionSheet
      E.on $ course E.^. CourseId E.==. sheet E.^. SheetCourse
      E.where_ $ submissionUser E.^. SubmissionUserUser E.==. E.val authId
           E.&&. sheet          E.^. SheetName          E.==. E.val shn
           E.&&. course         E.^. CourseShorthand    E.==. E.val csh
           E.&&. course         E.^. CourseSchool       E.==. E.val ssh
           E.&&. course         E.^. CourseTerm         E.==. E.val tid
      return $ submission E.^. SubmissionId
    hoistMaybe $ submissions ^? _head . _Value
  cID <- encrypt sid
  redirectAccess $ CSubmissionR tid ssh csh shn cID SubShowR
