module Hydra.Tx.HeadParameters where

import Hydra.Prelude

import Data.List (nub)
import Hydra.Tx.ContestationPeriod (ContestationPeriod)
import Hydra.Tx.Environment (Environment (..))
import Hydra.Tx.Party (Party (..))

-- | Contains the head's parameters as established in the initial transaction.
data HeadParameters = HeadParameters
  { HeadParameters -> ContestationPeriod
contestationPeriod :: ContestationPeriod
  , HeadParameters -> [Party]
parties :: [Party] -- NOTE(SN): The order of this list is important for leader selection.
  }
  deriving stock (HeadParameters -> HeadParameters -> Bool
(HeadParameters -> HeadParameters -> Bool)
-> (HeadParameters -> HeadParameters -> Bool) -> Eq HeadParameters
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: HeadParameters -> HeadParameters -> Bool
== :: HeadParameters -> HeadParameters -> Bool
$c/= :: HeadParameters -> HeadParameters -> Bool
/= :: HeadParameters -> HeadParameters -> Bool
Eq, Int -> HeadParameters -> ShowS
[HeadParameters] -> ShowS
HeadParameters -> String
(Int -> HeadParameters -> ShowS)
-> (HeadParameters -> String)
-> ([HeadParameters] -> ShowS)
-> Show HeadParameters
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> HeadParameters -> ShowS
showsPrec :: Int -> HeadParameters -> ShowS
$cshow :: HeadParameters -> String
show :: HeadParameters -> String
$cshowList :: [HeadParameters] -> ShowS
showList :: [HeadParameters] -> ShowS
Show, (forall x. HeadParameters -> Rep HeadParameters x)
-> (forall x. Rep HeadParameters x -> HeadParameters)
-> Generic HeadParameters
forall x. Rep HeadParameters x -> HeadParameters
forall x. HeadParameters -> Rep HeadParameters x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. HeadParameters -> Rep HeadParameters x
from :: forall x. HeadParameters -> Rep HeadParameters x
$cto :: forall x. Rep HeadParameters x -> HeadParameters
to :: forall x. Rep HeadParameters x -> HeadParameters
Generic)
  deriving anyclass ([HeadParameters] -> Value
[HeadParameters] -> Encoding
HeadParameters -> Bool
HeadParameters -> Value
HeadParameters -> Encoding
(HeadParameters -> Value)
-> (HeadParameters -> Encoding)
-> ([HeadParameters] -> Value)
-> ([HeadParameters] -> Encoding)
-> (HeadParameters -> Bool)
-> ToJSON HeadParameters
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: HeadParameters -> Value
toJSON :: HeadParameters -> Value
$ctoEncoding :: HeadParameters -> Encoding
toEncoding :: HeadParameters -> Encoding
$ctoJSONList :: [HeadParameters] -> Value
toJSONList :: [HeadParameters] -> Value
$ctoEncodingList :: [HeadParameters] -> Encoding
toEncodingList :: [HeadParameters] -> Encoding
$comitField :: HeadParameters -> Bool
omitField :: HeadParameters -> Bool
ToJSON, Maybe HeadParameters
Value -> Parser [HeadParameters]
Value -> Parser HeadParameters
(Value -> Parser HeadParameters)
-> (Value -> Parser [HeadParameters])
-> Maybe HeadParameters
-> FromJSON HeadParameters
forall a.
(Value -> Parser a)
-> (Value -> Parser [a]) -> Maybe a -> FromJSON a
$cparseJSON :: Value -> Parser HeadParameters
parseJSON :: Value -> Parser HeadParameters
$cparseJSONList :: Value -> Parser [HeadParameters]
parseJSONList :: Value -> Parser [HeadParameters]
$comittedField :: Maybe HeadParameters
omittedField :: Maybe HeadParameters
FromJSON)

instance Arbitrary HeadParameters where
  arbitrary :: Gen HeadParameters
arbitrary = HeadParameters -> HeadParameters
dedupParties (HeadParameters -> HeadParameters)
-> Gen HeadParameters -> Gen HeadParameters
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen HeadParameters
forall a.
(Generic a, GA UnsizedOpts (Rep a),
 UniformWeight (Weights_ (Rep a))) =>
Gen a
genericArbitrary
   where
    dedupParties :: HeadParameters -> HeadParameters
dedupParties HeadParameters{ContestationPeriod
$sel:contestationPeriod:HeadParameters :: HeadParameters -> ContestationPeriod
contestationPeriod :: ContestationPeriod
contestationPeriod, [Party]
$sel:parties:HeadParameters :: HeadParameters -> [Party]
parties :: [Party]
parties} =
      HeadParameters{ContestationPeriod
$sel:contestationPeriod:HeadParameters :: ContestationPeriod
contestationPeriod :: ContestationPeriod
contestationPeriod, $sel:parties:HeadParameters :: [Party]
parties = [Party] -> [Party]
forall a. Eq a => [a] -> [a]
nub [Party]
parties}

-- | Make 'HeadParameters' that are consistent with the given 'Environment'.
mkHeadParameters :: Environment -> HeadParameters
mkHeadParameters :: Environment -> HeadParameters
mkHeadParameters Environment{Party
party :: Party
$sel:party:Environment :: Environment -> Party
party, [Party]
otherParties :: [Party]
$sel:otherParties:Environment :: Environment -> [Party]
otherParties, ContestationPeriod
contestationPeriod :: ContestationPeriod
$sel:contestationPeriod:Environment :: Environment -> ContestationPeriod
contestationPeriod} =
  HeadParameters{ContestationPeriod
$sel:contestationPeriod:HeadParameters :: ContestationPeriod
contestationPeriod :: ContestationPeriod
contestationPeriod, $sel:parties:HeadParameters :: [Party]
parties = Party
party Party -> [Party] -> [Party]
forall a. a -> [a] -> [a]
: [Party]
otherParties}