{-# LANGUAGE TemplateHaskell #-}

module System.Nemesis.Type where

import Control.Lens
import Control.Monad.State (StateT)
import Data.Function (on)
import Data.List (intercalate)
import Data.Map (Map)
import Prelude hiding ((-))

newtype ShowIO = ShowIO {unShowIO :: IO () }

instance Show ShowIO where
  show _ = "IO"

data Task = Task
  {
    _name        :: String
  , _action      :: ShowIO
  , _deps        :: [String]
  , _description :: Maybe String
  , _namespace   :: [String]
  }
  deriving (Show)

emptyTask :: Task
emptyTask = Task mempty (ShowIO (pure ())) mempty mempty mempty

makeLenses ''Task

data Nemesis = Nemesis
  {
    _tasks            :: Map String Task
  , _target           :: String
  , _currentDesc      :: Maybe String
  , _currentNamespace :: [String]
  }
  deriving (Show)

emptyNemesis :: Nemesis
emptyNemesis = Nemesis mempty mempty mempty mempty

makeLenses ''Nemesis

instance Eq Task where
  (==) = (==) `on` (view name)

fullName :: Task -> String
fullName t = intercalate "/" . reverse $ (t ^. name : t ^. namespace)

instance Ord Task where
  compare = compare `on` fullName

type Unit = StateT Nemesis IO ()