module Test.SBench.Options
  ( ProfParam (..)   -- | re-export from "Profiling.Heap.Process"
  , Breakdown (..)   -- | re-export from "Profiling.Heap.Process"
  , Restriction (..) -- | re-export from "Profiling.Heap.Process"
  , Imports
  , CompilerOptions (..)
  , ProgramArguments (..)
  , MemoryOptions (..)
  , ProfilingOptions (..)
  , Repetitions (..)
  , ThreadNum (..)
  , MemUnit (..)
  , MemSize (..)
  , TestOpts (..)
  , RuntimeOptions (..)
  , EvalMod(..)
  , NormalInput
  , opts2string
  , Title
  ) where

import Profiling.Heap.Process ( ProfParam (..)
                              , Breakdown (..)
                              , Restriction (..)
                              )

import Data.List ( foldl' )

data TestOpts = TOpts
  { cOpts :: CompilerOptions
  , rOpts :: RuntimeOptions
  , reps  :: Maybe Repetitions
  , nfInp :: NormalInput
  }

type CompilerOptions = [String]

data RuntimeOptions = ROpts
  { threadNum :: Maybe ThreadNum
  , profOpts  :: ProfilingOptions
  , memOpts   :: MemoryOptions
  , progArgs  :: ProgramArguments
  }

instance Show RuntimeOptions where
   show rtopts = 
     let showProgArgs  = opts2string $ progArgs rtopts
         showMemOpts   = opts2string $ map show $ memOpts rtopts
         showThreadNum = case threadNum rtopts of
                           Nothing -> ""
                           Just i  -> "-N" ++ show i
         showProfOpts  = opts2string $ map show $ profOpts rtopts 
     in opts2string [showProgArgs, showMemOpts, showThreadNum, showProfOpts]

type ThreadNum        = Int
type ProfilingOptions = [ProfParam]
type MemoryOptions    = [MemSize]

data MemSize =   Heap  Int MemUnit 
               | Stack Int MemUnit

instance Show MemSize where
    show (Heap  a m) = "-H" ++ show a ++ show m
    show (Stack a m) = "-K" ++ show a ++ show m

data MemUnit = G | M | K | B

instance Show MemUnit where
    show G = "G"
    show M = "M"
    show K = "K"
    show B = "B"

type ProgramArguments = [String]

type Repetitions = Int
type NormalInput = Bool

data EvalMod = NF | WHNF

instance Show EvalMod where
  show NF   = "nf"
  show WHNF = "whnf"

type Imports = [String]


opts2string :: [String] -> String
opts2string = maybeTail . foldl' (\x y -> x ++ " " ++ y) ""
  where
    maybeTail []     = []
    maybeTail (x:xs) = xs

type Title = String