{-# OPTIONS_GHC -fno-warn-deprecations #-}
module Potato.Flow.DebugHelpers where

import           Relude
import Control.Monad.Writer

import qualified Data.List as L
import Control.Exception (assert)

-- prob just replace with show? Why do you ever want to not potato show?
-- the reason is becaues potatoShow doesn't show all information, but whatever it's fine
class PotatoShow a where
  potatoShow :: a -> Text

showFoldable :: (Foldable f, Show a) => f a -> Text
showFoldable :: forall (f :: * -> *) a. (Foldable f, Show a) => f a -> Text
showFoldable = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\Text
acc a
x -> Text
acc forall a. Semigroup a => a -> a -> a
<> forall b a. (Show a, IsString b) => a -> b
show a
x forall a. Semigroup a => a -> a -> a
<> Text
"\n") Text
""

assertShowAndDump  :: (HasCallStack, Show a) => a -> Bool -> b -> b
assertShowAndDump :: forall a b. (HasCallStack, Show a) => a -> Bool -> b -> b
assertShowAndDump a
a Bool
v b
b = if Bool
v
  then b
b
  else forall a t. (HasCallStack, IsText t) => t -> a
error forall a b. (a -> b) -> a -> b
$ Text
"assert failed:\n" forall a. Semigroup a => a -> a -> a
<> forall b a. (Show a, IsString b) => a -> b
show a
a

assertPotatoShowAndDump :: (HasCallStack, PotatoShow a) => a -> Bool -> b -> b
assertPotatoShowAndDump :: forall a b. (HasCallStack, PotatoShow a) => a -> Bool -> b -> b
assertPotatoShowAndDump a
a Bool
v b
b = if Bool
v
  then b
b
  else forall a t. (HasCallStack, IsText t) => t -> a
error forall a b. (a -> b) -> a -> b
$ Text
"assert failed:\n" forall a. Semigroup a => a -> a -> a
<> forall a. PotatoShow a => a -> Text
potatoShow a
a

traceWith :: (a -> String) -> a -> a
traceWith :: forall a. (a -> String) -> a -> a
traceWith a -> String
f a
x = forall a. String -> a -> a
trace (a -> String
f a
x) a
x

traceShowIdWithLabel :: (Show a) => String -> a -> a
traceShowIdWithLabel :: forall a. Show a => String -> a -> a
traceShowIdWithLabel String
label a
x = forall a. String -> a -> a
trace (String
label forall a. Semigroup a => a -> a -> a
<> String
": " forall a. Semigroup a => a -> a -> a
<> forall b a. (Show a, IsString b) => a -> b
show a
x) a
x


-- TODO decide if we want to use this??? Too much???
data PotatoLoggerLevel = PLL_Debug | PLL_Info | PLL_Warn | PLL_Error
data PotatoLoggerComponent = PLC_None | PLC_Goat

class MonadPotatoLogger m where
  potatoLog :: PotatoLoggerLevel -> PotatoLoggerComponent -> Text -> m ()

data PotatoLoggerObject = PotatoLoggerObject PotatoLoggerLevel PotatoLoggerComponent Text

type PotatoLogger = Writer [PotatoLoggerObject]

instance MonadPotatoLogger PotatoLogger where
  potatoLog :: PotatoLoggerLevel
-> PotatoLoggerComponent -> Text -> PotatoLogger ()
potatoLog PotatoLoggerLevel
l PotatoLoggerComponent
c Text
t = forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell forall a b. (a -> b) -> a -> b
$ [PotatoLoggerLevel
-> PotatoLoggerComponent -> Text -> PotatoLoggerObject
PotatoLoggerObject PotatoLoggerLevel
l PotatoLoggerComponent
c Text
t]


debugBangBang :: (HasCallStack) => [a] -> Int -> a
debugBangBang :: forall a. HasCallStack => [a] -> Int -> a
debugBangBang [a]
l Int
i = forall a. HasCallStack => Bool -> a -> a
assert (Int
i forall a. Ord a => a -> a -> Bool
>=Int
0 Bool -> Bool -> Bool
&& Int
i forall a. Ord a => a -> a -> Bool
< forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
l) ([a]
l forall a. [a] -> Int -> a
L.!! Int
i)