-- SPDX-FileCopyrightText: 2021 Oxhead Alpha
-- SPDX-License-Identifier: LicenseRef-MIT-OA

module Hedgehog.Gen.Tezos.Core
  ( genChainId
  , genMutez
  , genTimestamp
  ) where

import Hedgehog (MonadGen, Range)
import Hedgehog.Gen qualified as Gen
import Hedgehog.Range qualified as Range

import Morley.Tezos.Core
  (ChainId(..), Mutez(..), Timestamp, mkMutez, timestampFromSeconds, timestampToSeconds)

import Hedgehog.Range.Defaults ()

genChainId :: MonadGen m => m ChainId
genChainId :: forall (m :: * -> *). MonadGen m => m ChainId
genChainId = ByteString -> ChainId
UnsafeChainId (ByteString -> ChainId) -> m ByteString -> m ChainId
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Range Int -> m ByteString
forall (m :: * -> *). MonadGen m => Range Int -> m ByteString
Gen.bytes (Int -> Range Int
forall a. a -> Range a
Range.singleton Int
4)

-- | Generates an arbitrary `Mutez` value constrained to the given range.
genMutez :: MonadGen m => Range Mutez -> m Mutez
genMutez :: forall (m :: * -> *). MonadGen m => Range Mutez -> m Mutez
genMutez Range Mutez
range = Either Text Mutez -> Mutez
forall a b. (HasCallStack, Buildable a) => Either a b -> b
unsafe (Either Text Mutez -> Mutez)
-> (Word64 -> Either Text Mutez) -> Word64 -> Mutez
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Either Text Mutez
forall i. Integral i => i -> Either Text Mutez
mkMutez (Word64 -> Mutez) -> m Word64 -> m Mutez
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Range Word64 -> m Word64
forall (m :: * -> *). MonadGen m => Range Word64 -> m Word64
Gen.word64 (Word63 -> Word64
forall a b. (Integral a, Integral b, CheckIntSubType a b) => a -> b
fromIntegral (Word63 -> Word64) -> (Mutez -> Word63) -> Mutez -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Mutez -> Word63
unMutez (Mutez -> Word64) -> Range Mutez -> Range Word64
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Range Mutez
range)

genTimestamp :: MonadGen m => Range Timestamp -> m Timestamp
genTimestamp :: forall (m :: * -> *). MonadGen m => Range Timestamp -> m Timestamp
genTimestamp Range Timestamp
range =
  Integer -> Timestamp
timestampFromSeconds (Integer -> Timestamp) -> m Integer -> m Timestamp
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Range Integer -> m Integer
forall (m :: * -> *) a. (MonadGen m, Integral a) => Range a -> m a
Gen.integral (Timestamp -> Integer
forall a. Integral a => Timestamp -> a
timestampToSeconds (Timestamp -> Integer) -> Range Timestamp -> Range Integer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Range Timestamp
range)