{-|
Copyright   : (C) 2021, QBayLogic B.V.
License     : BSD2 (see the file LICENSE)
Maintainer  : QBayLogic B.V. <devops@qbaylogic.com>

Random generation of types from "Clash.Signal.Internal".
-}

{-# LANGUAGE CPP #-}

module Clash.Hedgehog.Signal
  ( genSignal
  , genActiveEdge
  , genInitBehavior
  , genResetKind
  , genResetPolarity
  ) where

#if !MIN_VERSION_base(4,18,0)
import Control.Applicative (liftA2)
#endif
import Hedgehog (MonadGen)
import qualified Hedgehog.Gen as Gen

import Clash.Signal.Internal

genSignal :: (MonadGen m) => m a -> m (Signal dom a)
genSignal :: m a -> m (Signal dom a)
genSignal m a
genElem = (a -> Signal dom a -> Signal dom a)
-> m a -> m (Signal dom a) -> m (Signal dom a)
forall (f :: Type -> Type) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> Signal dom a -> Signal dom a
forall (dom :: Domain) a. a -> Signal dom a -> Signal dom a
(:-) m a
genElem (m a -> m (Signal dom a)
forall (m :: Type -> Type) a (dom :: Domain).
MonadGen m =>
m a -> m (Signal dom a)
genSignal m a
genElem)

genActiveEdge :: (MonadGen m) => m ActiveEdge
genActiveEdge :: m ActiveEdge
genActiveEdge = [ActiveEdge] -> m ActiveEdge
forall (f :: Type -> Type) (m :: Type -> Type) a.
(Foldable f, MonadGen m) =>
f a -> m a
Gen.element [ActiveEdge
Rising, ActiveEdge
Falling]

genInitBehavior :: (MonadGen m) => m InitBehavior
genInitBehavior :: m InitBehavior
genInitBehavior = [InitBehavior] -> m InitBehavior
forall (f :: Type -> Type) (m :: Type -> Type) a.
(Foldable f, MonadGen m) =>
f a -> m a
Gen.element [InitBehavior
Unknown, InitBehavior
Defined]

genResetKind :: (MonadGen m) => m ResetKind
genResetKind :: m ResetKind
genResetKind = [ResetKind] -> m ResetKind
forall (f :: Type -> Type) (m :: Type -> Type) a.
(Foldable f, MonadGen m) =>
f a -> m a
Gen.element [ResetKind
Asynchronous, ResetKind
Synchronous]

genResetPolarity :: (MonadGen m) => m ResetPolarity
genResetPolarity :: m ResetPolarity
genResetPolarity = [ResetPolarity] -> m ResetPolarity
forall (f :: Type -> Type) (m :: Type -> Type) a.
(Foldable f, MonadGen m) =>
f a -> m a
Gen.element [ResetPolarity
ActiveHigh, ResetPolarity
ActiveLow]

-- TODO Generate a full domain configuration.
-- We probably want some type like SomeSDomainConfiguration to generate GADTs