{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

module Test.Cardano.Ledger.Conformance.Utils where

import Cardano.Crypto.Hash (ByteString, Hash, HashAlgorithm, hashFromBytes, hashToBytes, sizeHash)
import Cardano.Crypto.Util (bytesToNatural, naturalToBytes)
import qualified Data.ByteString.Base16 as B16
import Data.Data (Proxy (..))
import Test.Cardano.Ledger.TreeDiff (Expr, ToExpr (..))

agdaHashToBytes :: Int -> Integer -> ByteString
agdaHashToBytes :: Int -> Integer -> ByteString
agdaHashToBytes Int
hs = ByteString -> ByteString
B16.encode (ByteString -> ByteString)
-> (Integer -> ByteString) -> Integer -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Natural -> ByteString
naturalToBytes Int
hs (Natural -> ByteString)
-> (Integer -> Natural) -> Integer -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Natural
forall a. Num a => Integer -> a
fromInteger

agdaHashToExpr :: Int -> Integer -> Expr
agdaHashToExpr :: Int -> Integer -> Expr
agdaHashToExpr Int
hs = ByteString -> Expr
forall a. ToExpr a => a -> Expr
toExpr (ByteString -> Expr) -> (Integer -> ByteString) -> Integer -> Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Integer -> ByteString
agdaHashToBytes Int
hs

hashToInteger :: Hash a b -> Integer
hashToInteger :: forall a b. Hash a b -> Integer
hashToInteger = Natural -> Integer
forall a. Integral a => a -> Integer
toInteger (Natural -> Integer)
-> (Hash a b -> Natural) -> Hash a b -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Natural
bytesToNatural (ByteString -> Natural)
-> (Hash a b -> ByteString) -> Hash a b -> Natural
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Hash a b -> ByteString
forall h a. Hash h a -> ByteString
hashToBytes

integerToHash :: forall h a. HashAlgorithm h => Integer -> Maybe (Hash h a)
integerToHash :: forall h a. HashAlgorithm h => Integer -> Maybe (Hash h a)
integerToHash = ByteString -> Maybe (Hash h a)
forall h a. HashAlgorithm h => ByteString -> Maybe (Hash h a)
hashFromBytes (ByteString -> Maybe (Hash h a))
-> (Integer -> ByteString) -> Integer -> Maybe (Hash h a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Natural -> ByteString
naturalToBytes (Word -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word -> Int) -> (Proxy h -> Word) -> Proxy h -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy h -> Word
forall h (proxy :: * -> *). HashAlgorithm h => proxy h -> Word
sizeHash (Proxy h -> Int) -> Proxy h -> Int
forall a b. (a -> b) -> a -> b
$ forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @h) (Natural -> ByteString)
-> (Integer -> Natural) -> Integer -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Natural
forall a. Num a => Integer -> a
fromInteger