content: -- |Test the code generated by the Generics implementation of Flat
  {-# LANGUAGE DeriveAnyClass     #-}
  {-# LANGUAGE StandaloneDeriving #-}
  {-# LANGUAGE TemplateHaskell    #-}
  
  {-# OPTIONS_GHC -O2 -fplugin Test.Inspection.Plugin #-}
  
  import Control.Monad
  import Data.ByteString (ByteString)
  import Data.Maybe
  import Data.ZigZag
  import PlutusCore.Flat
  import PlutusCore.Flat.Encoder.Prim
  import PlutusCore.Flat.Encoder.Strict
  import PlutusCore.Flat.Types
  import Test.Data
  import Test.Data.Flat
  import Test.E
  import Test.E.Flat
  import Test.Inspection
  
  
  -- deriving instance Flat E2
  -- deriving instance Flat E3
  -- deriving instance Flat E4
  -- deriving instance Flat E8
  -- deriving instance Flat E16
  -- deriving instance Flat E17
  -- deriving instance Flat E32
  -- deriving instance Flat E256
  -- deriving instance Flat E258
  add2 :: NumBits -> NumBits
  add2 n = n + 2
  
  v1 :: NumBits
  v1 = 1
  
  v2 :: NumBits
  v2 = 2
  
  v3 :: NumBits
  v3 = 3
  
  v4 :: NumBits
  v4 = 4
  
  v5 :: NumBits
  v5 = 5
  
  v6 :: NumBits
  v6 = 6
  
  v8 :: NumBits
  v8 = 8
  
  s4 :: NumBits
  s4 = size E4_1 0
  
  sz2 :: NumBits -> NumBits
  sz2 = size E2_1
  
  f1 = encode E2_1
  
  tte = Encoding $ eTrueF >=> eTrueF
  
  ttte = Encoding $ eTrueF >=> eTrueF >=> eTrueF
  
  ff = eFalseF >=> eFalseF
  
  ft = eFalseF >=> eTrueF
  
  f2 = encode E2_2
  
  f4 = encode E4_4
  
  f8 = encode E8_8
  
  -- f32 :: Encoding
  f32 = encode E32_1
  
  f32_32 = flat E32_32
  
  one = encode One
  
  five = encode Five
  
  encE2 = encode :: (E2 -> Encoding)
  
  fl2 = flat E2_2
  
  leaf = encode (Leaf Five)
  
  dN = decode :: Get N
  
  -- sz :: Int
  sz = getSize E4_1
  
  sizeBool :: Bool -> NumBits
  sizeBool b = size b 0
  
  const1 :: Bool -> NumBits
  const1 = const 1
  
  const3 :: E8 -> NumBits
  const3 = const 3
  
  size3 :: E3 -> NumBits
  size3 b = size b 0
  
  size3Code :: E3 -> NumBits
  size3Code b = case b of
    E3_1 -> 1
    E3_2 -> 2
    E3_3 -> 2
  
  size17 :: E17 -> NumBits
  size17 b = size b 0
  
  size17Code :: E17 -> NumBits
  size17Code b = case b of
    E17_16 -> 5
    E17_17 -> 5
    __     -> 4
  
  size8 :: E8 -> NumBits
  size8 b = size b 0
  
  size32 :: E32 -> NumBits
  size32 b = size b 0
  
  sz0 = getSize E4_3
  
  sz3_1 = getSize E3_1
  
  sz3_3 = getSize E3_3
  
  sz4 = getSize E4_3
  
  sz8 = getSize E8_3
  
  sz16 = getSize E16_7
  
  sz17_1 = getSize E17_1
  
  sz17_17 = getSize E17_17
  
  sz32 = getSize E32_13
  
  -- sz64 = getSize E64_33
  -- sz256 = getSize E256_1
  -- sz4 = getSize E4_3
  szl = getSize [False]
  
  szb = getSize False
  
  -- sz_direction = getSize North
  inspect $ hasNoGenerics 'szb
  
  inspect $ 'sizeBool === 'const1
  
  inspect $ 'size3 === 'size3Code
  
  inspect $ 'size17 === 'size17Code
  
  -- inspect $ 'size32 === 'const1
  -- almost but not quite
  -- inspect $ 'size8 === 'const3
  -- Verify that sizes are fully calculated at compilation time, for simple enumerations
  inspect $ 'szb === 'v1
  
  inspect $ 'sz3_1 === 'v1
  
  inspect $ 'sz3_3 === 'v2
  
  inspect $ 'sz4 === 'v2
  
  inspect $ 'sz8 === 'v3
  
  inspect $ 'sz16 === 'v4
  
  inspect $ 'sz17_1 === 'v4
  
  inspect $ 'sz17_17 === 'v5
  
  inspect $ 'sz32 === 'v5
  
  -- This fails, a long nested case statement is generated instead
  -- inspect $ 'sz256 === 'v8
  -- inspect $ 'f1 === 'f2
  
  -- FAILS
  -- inspect $ 'tte === 'f2
  
  -- inspect $ 'five === 'one
  -- inspect $ 'leaf === 'one
  
  -- FAILS
  -- inspect $ 'leaf === 'dN
  
  -- inspect $ 'fl2 === 'encE2
  -- inspect $ 'f8 === 'ttte
  -- inspect $ 'f1 === 'ttte
  -- inspect $ 'sz2 === 'add2
  -- inspect $ 'ft === 'ff
  
  
  -- d8 = zzDecode8
  -- d8s = zzDecode :: Word8 -> Int8
  
  -- d64 = zzDecode64
  -- d64s = zzDecode :: Word64 -> Int64
  
  -- e64 = zzEncode :: Int64 -> Word64
  
  ziza = zigZag :: Int64 -> Word64
  zazi = zagZig :: Word8 -> Int8
  
  u = undefined
  
  -- -- check that specialised decode generates the same code as custom decode function
  -- inspect $ 'd8 === 'd8s
  
  -- inspect $ 'd64 === 'd64s
  
  -- inspect $ 'e64 === 'ziza -- e64
  
  -- inspect $ 'zazi === 'd8s
  
  -- dec, dec1 :: Word8 -> Int8
  -- dec = zzDecode
  -- dec1 = zzDecode1
  -- inspect $ 'dec === 'dec1
  
  
  main :: IO ()
  main = return () -- print (sz, sz0)
  