{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wno-orphans #-}

module Cardano.Ledger.CanonicalState.Namespace.GovCommittee.V0 (
  GovCommitteeIn (..),
  GovCommitteeOut (..),
  CanonicalCommittee (..),
) where

import Cardano.Ledger.BaseTypes (EpochNo (..), StrictMaybe, UnitInterval)
import Cardano.Ledger.CanonicalState.BasicTypes ()
import Cardano.Ledger.CanonicalState.Namespace (Era, NamespaceEra)
import Cardano.Ledger.Credential (Credential (..))
import Cardano.Ledger.Keys (KeyRole (ColdCommitteeRole))
import Cardano.SCLS.CBOR.Canonical.Decoder (FromCanonicalCBOR (..))
import Cardano.SCLS.CBOR.Canonical.Encoder (ToCanonicalCBOR (..))
import Cardano.SCLS.Entry.IsKey (IsKey (..))
import Cardano.SCLS.NamespaceCodec (
  CanonicalCBOREntryDecoder (..),
  CanonicalCBOREntryEncoder (..),
  KnownNamespace (..),
  namespaceKeySize,
 )
import Cardano.SCLS.Versioned (Versioned (Versioned))
import qualified Data.Map.Strict as Map
import Data.MemPack.ByteOrdered (packWord64beM, unpackBigEndianM)
import Data.Proxy (Proxy (..))
import GHC.Generics (Generic)

instance (Era era, NamespaceEra "gov/committee/v0" ~ era) => KnownNamespace "gov/committee/v0" where
  type NamespaceKey "gov/committee/v0" = GovCommitteeIn
  type NamespaceEntry "gov/committee/v0" = GovCommitteeOut

instance
  (Era era, NamespaceEra "gov/committee/v0" ~ era) =>
  CanonicalCBOREntryEncoder "gov/committee/v0" GovCommitteeOut
  where
  encodeEntry :: GovCommitteeOut -> CanonicalEncoding
encodeEntry (GovCommitteeOut StrictMaybe CanonicalCommittee
n) = Proxy "gov/committee/v0"
-> StrictMaybe CanonicalCommittee -> CanonicalEncoding
forall (v :: Symbol) a (proxy :: Symbol -> *).
ToCanonicalCBOR v a =>
proxy v -> a -> CanonicalEncoding
forall (proxy :: Symbol -> *).
proxy "gov/committee/v0"
-> StrictMaybe CanonicalCommittee -> CanonicalEncoding
toCanonicalCBOR (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @"gov/committee/v0") StrictMaybe CanonicalCommittee
n

instance
  (Era era, NamespaceEra "gov/committee/v0" ~ era) =>
  CanonicalCBOREntryDecoder "gov/committee/v0" GovCommitteeOut
  where
  decodeEntry :: forall s.
CanonicalDecoder s (Versioned "gov/committee/v0" GovCommitteeOut)
decodeEntry = (StrictMaybe CanonicalCommittee -> GovCommitteeOut)
-> Versioned "gov/committee/v0" (StrictMaybe CanonicalCommittee)
-> Versioned "gov/committee/v0" GovCommitteeOut
forall a b.
(a -> b)
-> Versioned "gov/committee/v0" a -> Versioned "gov/committee/v0" b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap StrictMaybe CanonicalCommittee -> GovCommitteeOut
GovCommitteeOut (Versioned "gov/committee/v0" (StrictMaybe CanonicalCommittee)
 -> Versioned "gov/committee/v0" GovCommitteeOut)
-> CanonicalDecoder
     s (Versioned "gov/committee/v0" (StrictMaybe CanonicalCommittee))
-> CanonicalDecoder
     s (Versioned "gov/committee/v0" GovCommitteeOut)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CanonicalDecoder
  s (Versioned "gov/committee/v0" (StrictMaybe CanonicalCommittee))
forall s.
CanonicalDecoder
  s (Versioned "gov/committee/v0" (StrictMaybe CanonicalCommittee))
forall (v :: Symbol) a s.
FromCanonicalCBOR v a =>
CanonicalDecoder s (Versioned v a)
fromCanonicalCBOR

newtype GovCommitteeIn = GovCommitteeIn EpochNo
  deriving (GovCommitteeIn -> GovCommitteeIn -> Bool
(GovCommitteeIn -> GovCommitteeIn -> Bool)
-> (GovCommitteeIn -> GovCommitteeIn -> Bool) -> Eq GovCommitteeIn
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: GovCommitteeIn -> GovCommitteeIn -> Bool
== :: GovCommitteeIn -> GovCommitteeIn -> Bool
$c/= :: GovCommitteeIn -> GovCommitteeIn -> Bool
/= :: GovCommitteeIn -> GovCommitteeIn -> Bool
Eq, Eq GovCommitteeIn
Eq GovCommitteeIn =>
(GovCommitteeIn -> GovCommitteeIn -> Ordering)
-> (GovCommitteeIn -> GovCommitteeIn -> Bool)
-> (GovCommitteeIn -> GovCommitteeIn -> Bool)
-> (GovCommitteeIn -> GovCommitteeIn -> Bool)
-> (GovCommitteeIn -> GovCommitteeIn -> Bool)
-> (GovCommitteeIn -> GovCommitteeIn -> GovCommitteeIn)
-> (GovCommitteeIn -> GovCommitteeIn -> GovCommitteeIn)
-> Ord GovCommitteeIn
GovCommitteeIn -> GovCommitteeIn -> Bool
GovCommitteeIn -> GovCommitteeIn -> Ordering
GovCommitteeIn -> GovCommitteeIn -> GovCommitteeIn
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: GovCommitteeIn -> GovCommitteeIn -> Ordering
compare :: GovCommitteeIn -> GovCommitteeIn -> Ordering
$c< :: GovCommitteeIn -> GovCommitteeIn -> Bool
< :: GovCommitteeIn -> GovCommitteeIn -> Bool
$c<= :: GovCommitteeIn -> GovCommitteeIn -> Bool
<= :: GovCommitteeIn -> GovCommitteeIn -> Bool
$c> :: GovCommitteeIn -> GovCommitteeIn -> Bool
> :: GovCommitteeIn -> GovCommitteeIn -> Bool
$c>= :: GovCommitteeIn -> GovCommitteeIn -> Bool
>= :: GovCommitteeIn -> GovCommitteeIn -> Bool
$cmax :: GovCommitteeIn -> GovCommitteeIn -> GovCommitteeIn
max :: GovCommitteeIn -> GovCommitteeIn -> GovCommitteeIn
$cmin :: GovCommitteeIn -> GovCommitteeIn -> GovCommitteeIn
min :: GovCommitteeIn -> GovCommitteeIn -> GovCommitteeIn
Ord, Int -> GovCommitteeIn -> ShowS
[GovCommitteeIn] -> ShowS
GovCommitteeIn -> String
(Int -> GovCommitteeIn -> ShowS)
-> (GovCommitteeIn -> String)
-> ([GovCommitteeIn] -> ShowS)
-> Show GovCommitteeIn
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> GovCommitteeIn -> ShowS
showsPrec :: Int -> GovCommitteeIn -> ShowS
$cshow :: GovCommitteeIn -> String
show :: GovCommitteeIn -> String
$cshowList :: [GovCommitteeIn] -> ShowS
showList :: [GovCommitteeIn] -> ShowS
Show)

newtype GovCommitteeOut = GovCommitteeOut (StrictMaybe CanonicalCommittee)
  deriving ((forall x. GovCommitteeOut -> Rep GovCommitteeOut x)
-> (forall x. Rep GovCommitteeOut x -> GovCommitteeOut)
-> Generic GovCommitteeOut
forall x. Rep GovCommitteeOut x -> GovCommitteeOut
forall x. GovCommitteeOut -> Rep GovCommitteeOut x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. GovCommitteeOut -> Rep GovCommitteeOut x
from :: forall x. GovCommitteeOut -> Rep GovCommitteeOut x
$cto :: forall x. Rep GovCommitteeOut x -> GovCommitteeOut
to :: forall x. Rep GovCommitteeOut x -> GovCommitteeOut
Generic, GovCommitteeOut -> GovCommitteeOut -> Bool
(GovCommitteeOut -> GovCommitteeOut -> Bool)
-> (GovCommitteeOut -> GovCommitteeOut -> Bool)
-> Eq GovCommitteeOut
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: GovCommitteeOut -> GovCommitteeOut -> Bool
== :: GovCommitteeOut -> GovCommitteeOut -> Bool
$c/= :: GovCommitteeOut -> GovCommitteeOut -> Bool
/= :: GovCommitteeOut -> GovCommitteeOut -> Bool
Eq, Int -> GovCommitteeOut -> ShowS
[GovCommitteeOut] -> ShowS
GovCommitteeOut -> String
(Int -> GovCommitteeOut -> ShowS)
-> (GovCommitteeOut -> String)
-> ([GovCommitteeOut] -> ShowS)
-> Show GovCommitteeOut
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> GovCommitteeOut -> ShowS
showsPrec :: Int -> GovCommitteeOut -> ShowS
$cshow :: GovCommitteeOut -> String
show :: GovCommitteeOut -> String
$cshowList :: [GovCommitteeOut] -> ShowS
showList :: [GovCommitteeOut] -> ShowS
Show)

deriving newtype instance
  ToCanonicalCBOR "gov/committee/v0" (StrictMaybe CanonicalCommittee) =>
  ToCanonicalCBOR "gov/committee/v0" GovCommitteeOut

deriving newtype instance
  FromCanonicalCBOR "gov/committee/v0" (StrictMaybe CanonicalCommittee) =>
  FromCanonicalCBOR "gov/committee/v0" GovCommitteeOut

instance IsKey GovCommitteeIn where
  keySize :: Int
keySize = forall (ns :: Symbol). KnownNat (NamespaceKeySize ns) => Int
namespaceKeySize @"gov/committee/v0"
  packKeyM :: forall b. GovCommitteeIn -> Pack b ()
packKeyM (GovCommitteeIn (EpochNo Word64
no)) = Word64 -> Pack b ()
forall s. Word64 -> Pack s ()
packWord64beM Word64
no
  unpackKeyM :: forall b s. Buffer b => Unpack' s b GovCommitteeIn
unpackKeyM = do
    EpochNo -> GovCommitteeIn
GovCommitteeIn (EpochNo -> GovCommitteeIn)
-> (Word64 -> EpochNo) -> Word64 -> GovCommitteeIn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> EpochNo
EpochNo (Word64 -> GovCommitteeIn)
-> Unpack s b Word64 -> Unpack s b GovCommitteeIn
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Unpack s b Word64
forall a b s. (Bytes a, MemPack a, Buffer b) => Unpack s b a
unpackBigEndianM

data CanonicalCommittee = CanonicalCommittee
  { CanonicalCommittee -> Map (Credential ColdCommitteeRole) EpochNo
committeeMembers :: !(Map.Map (Credential ColdCommitteeRole) EpochNo)
  , CanonicalCommittee -> UnitInterval
committeeThreshold :: !UnitInterval
  }
  deriving (CanonicalCommittee -> CanonicalCommittee -> Bool
(CanonicalCommittee -> CanonicalCommittee -> Bool)
-> (CanonicalCommittee -> CanonicalCommittee -> Bool)
-> Eq CanonicalCommittee
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CanonicalCommittee -> CanonicalCommittee -> Bool
== :: CanonicalCommittee -> CanonicalCommittee -> Bool
$c/= :: CanonicalCommittee -> CanonicalCommittee -> Bool
/= :: CanonicalCommittee -> CanonicalCommittee -> Bool
Eq, Int -> CanonicalCommittee -> ShowS
[CanonicalCommittee] -> ShowS
CanonicalCommittee -> String
(Int -> CanonicalCommittee -> ShowS)
-> (CanonicalCommittee -> String)
-> ([CanonicalCommittee] -> ShowS)
-> Show CanonicalCommittee
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CanonicalCommittee -> ShowS
showsPrec :: Int -> CanonicalCommittee -> ShowS
$cshow :: CanonicalCommittee -> String
show :: CanonicalCommittee -> String
$cshowList :: [CanonicalCommittee] -> ShowS
showList :: [CanonicalCommittee] -> ShowS
Show, (forall x. CanonicalCommittee -> Rep CanonicalCommittee x)
-> (forall x. Rep CanonicalCommittee x -> CanonicalCommittee)
-> Generic CanonicalCommittee
forall x. Rep CanonicalCommittee x -> CanonicalCommittee
forall x. CanonicalCommittee -> Rep CanonicalCommittee x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. CanonicalCommittee -> Rep CanonicalCommittee x
from :: forall x. CanonicalCommittee -> Rep CanonicalCommittee x
$cto :: forall x. Rep CanonicalCommittee x -> CanonicalCommittee
to :: forall x. Rep CanonicalCommittee x -> CanonicalCommittee
Generic)

instance (Era era, NamespaceEra v ~ era) => ToCanonicalCBOR v CanonicalCommittee where
  toCanonicalCBOR :: forall (proxy :: Symbol -> *).
proxy v -> CanonicalCommittee -> CanonicalEncoding
toCanonicalCBOR proxy v
v CanonicalCommittee {Map (Credential ColdCommitteeRole) EpochNo
UnitInterval
committeeMembers :: CanonicalCommittee -> Map (Credential ColdCommitteeRole) EpochNo
committeeThreshold :: CanonicalCommittee -> UnitInterval
committeeMembers :: Map (Credential ColdCommitteeRole) EpochNo
committeeThreshold :: UnitInterval
..} =
    proxy v
-> (Map (Credential ColdCommitteeRole) EpochNo, UnitInterval)
-> CanonicalEncoding
forall (v :: Symbol) a (proxy :: Symbol -> *).
ToCanonicalCBOR v a =>
proxy v -> a -> CanonicalEncoding
forall (proxy :: Symbol -> *).
proxy v
-> (Map (Credential ColdCommitteeRole) EpochNo, UnitInterval)
-> CanonicalEncoding
toCanonicalCBOR proxy v
v (Map (Credential ColdCommitteeRole) EpochNo
committeeMembers, UnitInterval
committeeThreshold)

instance (Era era, NamespaceEra v ~ era) => FromCanonicalCBOR v CanonicalCommittee where
  fromCanonicalCBOR :: forall s. CanonicalDecoder s (Versioned v CanonicalCommittee)
fromCanonicalCBOR = do
    Versioned (members, threshold) <- forall (v :: Symbol) a s.
FromCanonicalCBOR v a =>
CanonicalDecoder s (Versioned v a)
fromCanonicalCBOR @v
    return $
      Versioned $
        CanonicalCommittee {committeeMembers = members, committeeThreshold = threshold}