{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_HADDOCK show-extensions #-}

{-|
Module      : $Header$
Copyright   : (c) 2016 Deakin Software & Technology Innovation Lab
License     : BSD3

Maintainer  : Rhys Adams <rhys.adams@deakin.edu.au>
Stability   : unstable
Portability : portable
-}

module Eclogues.State.Types where

import Eclogues.Prelude
import qualified Eclogues.Job as Job

import Control.Lens.TH (makeClassy, makePrisms)
import Data.Default.Generics (Default)

-- TODO: test performance. it might be better to use stm-containers.

type Nodes   = HashMap Job.Name Job.AnyStatus
type Jobs    = HashMap Job.Name Job.Status
-- Dependencies is misleading, they're dependents in this case
type RevDeps = HashMap Job.Name Job.Dependencies
type Containers = HashMap Job.ContainerId UUID

data AppState = AppState { -- | Map of jobs names to status.
                           _nodes   :: Nodes
                           -- | Map of job names to jobs that depend on them
                           -- and have yet to terminate.
                         , _revDeps :: RevDeps
                         , _containers :: Containers }
                deriving (Generic, Show, Eq)

$(makePrisms ''Job.Dependencies)
$(makePrisms ''Job.AnyStatus)
$(makePrisms ''Job.Sealed)
$(makeClassy ''AppState)

job :: (HasAppState s) => Job.Name -> Traversal' s Job.Status
job n = nodes . ix n . _AJob

jobs :: (HasAppState s) => Traversal' s Job.Status
jobs = nodes . each . _AJob

instance Default AppState
