module Eg.ArithmeticFixture where

import Test.FIT.Fixture
import Test.FIT.Parse
import Data.IORef


data ArithmeticFixture = ArithmeticFixture
  { arithFixtureBase :: BaseFixture
  , arithFixtureX :: IORef Int
  , arithFixtureY :: IORef Int
  }

getX f = readIORef (arithFixtureX f)
getY f = readIORef (arithFixtureY f)
setX f p =
  writeIORef (arithFixtureX f) (read (bodyToText p)) >> return p
setY f p =
  writeIORef (arithFixtureY f) (read (bodyToText p)) >> return p
binOp f p op = do
  x <- getX f; y <- getY f
  check f p (op x y)


instance IsFixture ArithmeticFixture where
  baseFixture f = arithFixtureBase f
  -- skip first two rows
  doTable f p = do
    case parseParts p of
      (r1:r2:rs) -> do
        rs' <- doRows f (rs)
        return p { parseParts = (r1:r2:rs') }
      otherwise -> return p
  doCell f p 0 = setX f p
  doCell f p 1 = setY f p
  doCell f p 2 = binOp f p (+)
  doCell f p 3 = binOp f p (-)
  doCell f p 4 = binOp f p (*)
  doCell f p 5 = binOp f p div
  doCell f p _ = ignore f p


newArithFixture bf = do
  refx <- newIORef 0
  refy <- newIORef 0
  return (ArithmeticFixture bf refx refy)

processFixture :: ProcessFixture
processFixture bf p = do
  f <- newArithFixture bf
  doTable f p
