{- | Define a job type: a description of a task a user can run.

-}

{-# LANGUAGE ExistentialQuantification #-}

module Web.JobsUi.Types
  ( module Web.JobsUi.Types
  , module Export
  )
where

import qualified Data.Text as T
import Text.Digestive.Types as Export (Result(..))

-- | JobInfo is a description a job a user can run
--   @@a@@ is the structure built from the parameters.
data JobInfo a
  = JobInfo
  { jiType :: T.Text -- ^ The name of the job type.
  , jiInputs :: [Param] -- ^ Definition of user parameters.
  , jiParams :: a -> [T.Text]
    -- ^ Conversion from the job payload structure to presentable parameters.
  , jiConstructor :: [(T.Text, T.Text)] -> IO a
    -- ^ Construct a payload type from user entered parameters.
  , jiExec :: a -> IO T.Text
    -- ^ How to execute a job. Returns a presentable Html when the job succeeds.
  , jiNotify :: a -> (Result T.Text T.Text) -> IO ()
    -- ^ Will be run when job ends.
  }

-- | Defines a parameter for the user
data Param
  = Param
  { paramDesc :: T.Text
  , paramInputType :: ParamInputType
  , paramValidation :: T.Text -> IO (Result T.Text T.Text)
  }

-- | Input type
data ParamInputType
  = TextInput
  | TextOptions (IO [T.Text])

-- | Existential type for job. Let's us ignore the job payload internally.
data JobType
  = forall a. JobType
  { getJobInfo :: JobInfo a
  }