{-# OPTIONS_GHC -Wall  #-}
{-# LANGUAGE FlexibleInstances,UndecidableInstances,OverlappingInstances #-}

module QuickCover.Log where

import Data.IORef
import System.IO.Unsafe
import GHC.Conc
import Data.Data
import Data.Generics.Instances()
import Control.DeepSeq

gShowConstr :: Data a => a -> String
gShowConstr = showConstr . toConstr 
 
isLogging :: IORef Bool
isLogging = unsafePerformIO (newIORef False)

logger :: IORef ([(Int,Maybe String)])
{-# NOINLINE logger #-}
logger = unsafePerformIO (newIORef [])

class Data a => Log a where
  log :: String -> a -> a
  log x = let entry =  (read x ::Int,Just $ gShowConstr x) in
    pseq (unsafePerformIO $ do
           b  <- readIORef isLogging
           if b 
             then  
             modifyIORef' logger $ deepseq entry (entry :)
             else
             return ())
          

instance (Data a,Data b) => Log (a -> b) where
  log x = let entry = (read x :: Int,Nothing :: Maybe String) in
    pseq (unsafePerformIO $ do
             b  <- readIORef isLogging
             if b 
               then  
               modifyIORef' logger $ deepseq entry (entry:)
               else
               return ())
  
instance Data a => Log a where {}

{-
class Log a where
  log :: String -> a -> a
  log x = pseq (unsafePerformIO 
               $ modifyIORef logger 
               $ (++ [(read x ::Int,Nothing)]))

instance Log Bool where
  log x b = pseq (unsafePerformIO 
                 $ modifyIORef logger 
                 $ (++ [(read x :: Int,Just $ show b)])) b 
  
instance Log a where {}
-}