module Cron.Types
  ( Cron(..), Crontab
  , CronMatch(..)
  , CronAbsolute(..)
  , CronRepeat(..)
  ) where

import ClassyPrelude

import Utils.Lens.TH

import Data.Time 

import Numeric.Natural

import Data.HashMap.Strict (HashMap)
  

data CronMatch
  = CronMatchAny
  | CronMatchNone
  | CronMatchSome (NonNull (Set Natural))
  | CronMatchStep Natural
  | CronMatchContiguous Natural Natural
  | CronMatchIntersect CronMatch CronMatch
  | CronMatchUnion CronMatch CronMatch
  deriving (Eq, Show, Read)

data CronAbsolute
  = CronAsap
  | CronTimestamp
    { cronTimestamp :: LocalTime
    }
  | CronCalendar
    { cronYear, cronWeekOfYear, cronDayOfYear
    , cronMonth, cronWeekOfMonth, cronDayOfMonth
    , cronDayOfWeek
    , cronHour, cronMinute, cronSecond :: CronMatch
    }
  | CronNotScheduled
  deriving (Eq, Show, Read)

makeLenses_ ''CronAbsolute

data CronRepeat
  = CronRepeatOnChange
  | CronRepeatScheduled CronAbsolute
  | CronRepeatNever
  deriving (Eq, Show, Read)

data Cron = Cron
  { cronInitial :: CronAbsolute
  , cronRepeat :: CronRepeat
  , cronRateLimit :: NominalDiffTime
  , cronNotAfter :: Either NominalDiffTime CronAbsolute
  }
  deriving (Eq, Show)

makeLenses_ ''Cron

type Crontab a = HashMap a Cron
