content: module Main where
  
  -- import Control.Monad (forM_)
  import qualified Data.BloomFilter.Easy as B
  import Data.BloomFilter.Hash (Hashable (..), hash64)
  import qualified Data.ByteString.Char8 as SB
  import qualified Data.ByteString.Lazy.Char8 as LB
  import Data.Int (Int16, Int32, Int64, Int8)
  import Data.Word (Word16, Word32, Word64, Word8)
  -- import System.IO (BufferMode(..), hSetBuffering, stdout)
  
  --Testable
  
  import QCSupport (P (..))
  import Test.Framework (Test, defaultMain)
  import Test.Framework.Providers.QuickCheck2 (testProperty)
  import Test.QuickCheck (Property, choose, forAll, (==>))
  
  prop_pai :: (Hashable a) => a -> a -> P -> Bool
  prop_pai _ xs (P q) = let bf = B.easyList q [xs] in xs `B.elem` bf
  
  tests :: [Test]
  tests =
    [ testProperty "()" $ prop_pai (),
      testProperty "Bool" $ prop_pai (undefined :: Bool),
      testProperty "Ordering" $ prop_pai (undefined :: Ordering),
      testProperty "Char" $ prop_pai (undefined :: Char),
      testProperty "Int" $ prop_pai (undefined :: Int),
      testProperty "Float" $ prop_pai (undefined :: Float),
      testProperty "Double" $ prop_pai (undefined :: Double),
      testProperty "Int8" $ prop_pai (undefined :: Int8),
      testProperty "Int16" $ prop_pai (undefined :: Int16),
      testProperty "Int32" $ prop_pai (undefined :: Int32),
      testProperty "Int64" $ prop_pai (undefined :: Int64),
      testProperty "Word8" $ prop_pai (undefined :: Word8),
      testProperty "Word16" $ prop_pai (undefined :: Word16),
      testProperty "Word32" $ prop_pai (undefined :: Word32),
      testProperty "Word64" $ prop_pai (undefined :: Word64),
      testProperty "String" $ prop_pai (undefined :: String),
      testProperty "LB.ByteString" $ prop_pai (undefined :: LB.ByteString),
      testProperty "prop_rechunked_eq" prop_rechunked_eq
    ]
  
  rechunk :: Int64 -> LB.ByteString -> LB.ByteString
  rechunk k xs
    | k <= 0 = xs
    | otherwise = LB.fromChunks (go xs)
    where
      go s
        | LB.null s = []
        | otherwise =
          let (pre, suf) = LB.splitAt k s
           in repack pre : go suf
      repack = SB.concat . LB.toChunks
  
  -- Ensure that a property over a lazy ByteString holds if we change
  -- the chunk boundaries.
  prop_rechunked :: Eq a => (LB.ByteString -> a) -> LB.ByteString -> Property
  prop_rechunked f s =
    let l = LB.length s
     in l > 0 ==> forAll (choose (1, l - 1)) $ \k ->
          let n = k `mod` l
           in n > 0 ==> f s == f (rechunk n s)
  
  prop_rechunked_eq :: LB.ByteString -> Property
  prop_rechunked_eq = prop_rechunked hash64
  
  main :: IO ()
  main = defaultMain tests
  