{-# LANGUAGE TemplateHaskell #-}

module System.Nemesis.Type where

import           Control.Lens
import           Control.Monad.State hiding (State, join)
import           Data.Function
import           Data.List
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 ()