{-# LANGUAGE OverloadedStrings #-}

{-# OPTIONS -Wall #-}

module Network.DFINITY.RadixTree.Utilities
   ( createPrefix
   , createRoot
   , createRootFromNonce
   , defaultRoot
   ) where

import Codec.Serialise (serialise)
import Data.ByteString.Short (toShort)
import Data.Default.Class (def)

import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Builder as Builder

import qualified Crypto.Hash.BLAKE2.BLAKE2s as Blake2s

import Network.DFINITY.RadixTree.Bits
import Network.DFINITY.RadixTree.Types

createPrefix :: [Bool] -> Maybe RadixPrefix
createPrefix bits =
   if null bits
   then Nothing
   else Just $ fromBits bits

createRoot :: RadixNode -> RadixRoot
createRoot = toShort . blake2s_hashlazy 20 . serialise

createRootFromNonce :: Word -> RadixRoot
createRootFromNonce
  = toShort
    . Blake2s.hash 20 mempty
    . LBS.toStrict
    . Builder.toLazyByteString
    . Builder.wordDec

defaultRoot :: RadixRoot
defaultRoot = createRoot def

blake2s_hashlazy :: Int -> LBS.ByteString -> BS.ByteString
blake2s_hashlazy size
  = Blake2s.finalize size
    . LBS.foldlChunks (flip Blake2s.update) (Blake2s.initialize size)