{-# LANGUAGE DeriveDataTypeable #-}
{-| Data types describing the execution environment
    of virtual machine builds.
    'ExecEnv', 'Resources' and 'SharedDirectory' describe how
    "B9.LibVirtLXC" should configure and execute
    build scripts, as defined in "B9.ShellScript" and "B9.Vm".
    -}
module B9.ExecEnv (
    ExecEnv(..),
    Resources(..),
    noResources,
    SharedDirectory(..),
    CPUArch(..),
    RamSize(..),
    ) where

import Control.Parallel.Strategies
import Data.Binary
import Data.Data
import Data.Hashable
import Data.Semigroup as Sem
import B9.DiskImages
import GHC.Generics (Generic)

data ExecEnv = ExecEnv
    { envName :: String
    , envImageMounts :: [Mounted Image]
    , envSharedDirectories :: [SharedDirectory]
    , envResources :: Resources
    }
    deriving (Read,Show,Typeable,Data,Eq,Generic)

instance Hashable ExecEnv
instance Binary ExecEnv
instance NFData ExecEnv

data SharedDirectory
    = SharedDirectory FilePath
                      MountPoint
    | SharedDirectoryRO FilePath
                        MountPoint
    | SharedSources MountPoint
    deriving (Read,Show,Typeable,Data,Eq,Generic)

instance Hashable SharedDirectory
instance Binary SharedDirectory
instance NFData SharedDirectory

data Resources = Resources
    { maxMemory :: RamSize
    , cpuCount :: Int
    , cpuArch :: CPUArch
    } deriving (Eq,Read,Show,Typeable,Data,Generic)

instance Hashable Resources
instance Binary Resources
instance NFData Resources

instance Sem.Semigroup Resources where
  (<>) (Resources m c a) (Resources m' c' a') = Resources (m <> m') (max c c') (a <> a')

instance Monoid Resources where
    mempty = Resources mempty 1 mempty
    mappend  = (Sem.<>)

noResources :: Resources
noResources = mempty

data CPUArch
    = X86_64
    | I386
    deriving (Read,Show,Typeable,Data,Eq,Generic)

instance Hashable CPUArch
instance Binary CPUArch
instance NFData CPUArch

instance Sem.Semigroup CPUArch where
    I386 <> x = x
    X86_64 <> _ = X86_64

instance Monoid CPUArch where
    mempty = I386
    mappend = (Sem.<>)

data RamSize
    = RamSize Int
              SizeUnit
    | AutomaticRamSize
    deriving (Eq,Read,Show,Ord,Typeable,Data,Generic)

instance Hashable RamSize
instance Binary RamSize
instance NFData RamSize

instance Sem.Semigroup RamSize where
    AutomaticRamSize <> x = x
    x <> AutomaticRamSize = x
    r <> r' = max r r'

instance Monoid RamSize where
    mempty = AutomaticRamSize
    mappend = (Sem.<>)