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

module Cardano.CLI.EraBased.Governance.GenesisKeyDelegationCertificate.Run
  ( runGovernanceGenesisKeyDelegationCertificate
  )
where

import Cardano.Api
import Cardano.Api.Shelley

import Cardano.CLI.Compatible.Exception
import Cardano.CLI.Type.Key

import Data.Typeable (Typeable)

runGovernanceGenesisKeyDelegationCertificate
  :: forall era e
   . Typeable era
  => ShelleyToBabbageEra era
  -> VerificationKeyOrHashOrFile GenesisKey
  -> VerificationKeyOrHashOrFile GenesisDelegateKey
  -> VerificationKeyOrHashOrFile VrfKey
  -> File () Out
  -> CIO e ()
runGovernanceGenesisKeyDelegationCertificate :: forall era e.
Typeable era =>
ShelleyToBabbageEra era
-> VerificationKeyOrHashOrFile GenesisKey
-> VerificationKeyOrHashOrFile GenesisDelegateKey
-> VerificationKeyOrHashOrFile VrfKey
-> File () 'Out
-> CIO e ()
runGovernanceGenesisKeyDelegationCertificate
  ShelleyToBabbageEra era
stb
  VerificationKeyOrHashOrFile GenesisKey
genVkOrHashOrFp
  VerificationKeyOrHashOrFile GenesisDelegateKey
genDelVkOrHashOrFp
  VerificationKeyOrHashOrFile VrfKey
vrfVkOrHashOrFp
  File () 'Out
oFp = do
    Hash GenesisKey
genesisVkHash <-
      ExceptT (FileError InputDecodeError) IO (Hash GenesisKey)
-> RIO e (Hash GenesisKey)
forall e (m :: * -> *) a.
(HasCallStack, MonadIO m, Show e, Typeable e, Error e) =>
ExceptT e IO a -> m a
fromExceptTCli (ExceptT (FileError InputDecodeError) IO (Hash GenesisKey)
 -> RIO e (Hash GenesisKey))
-> ExceptT (FileError InputDecodeError) IO (Hash GenesisKey)
-> RIO e (Hash GenesisKey)
forall a b. (a -> b) -> a -> b
$
        VerificationKeyOrHashOrFile GenesisKey
-> ExceptT (FileError InputDecodeError) IO (Hash GenesisKey)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) keyrole.
(MonadIOTransError (FileError InputDecodeError) t m,
 Key keyrole) =>
VerificationKeyOrHashOrFile keyrole -> t m (Hash keyrole)
readVerificationKeyOrHashOrTextEnvFile VerificationKeyOrHashOrFile GenesisKey
genVkOrHashOrFp
    Hash GenesisDelegateKey
genesisDelVkHash <-
      ExceptT (FileError InputDecodeError) IO (Hash GenesisDelegateKey)
-> RIO e (Hash GenesisDelegateKey)
forall e (m :: * -> *) a.
(HasCallStack, MonadIO m, Show e, Typeable e, Error e) =>
ExceptT e IO a -> m a
fromExceptTCli (ExceptT (FileError InputDecodeError) IO (Hash GenesisDelegateKey)
 -> RIO e (Hash GenesisDelegateKey))
-> ExceptT
     (FileError InputDecodeError) IO (Hash GenesisDelegateKey)
-> RIO e (Hash GenesisDelegateKey)
forall a b. (a -> b) -> a -> b
$
        VerificationKeyOrHashOrFile GenesisDelegateKey
-> ExceptT
     (FileError InputDecodeError) IO (Hash GenesisDelegateKey)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) keyrole.
(MonadIOTransError (FileError InputDecodeError) t m,
 Key keyrole) =>
VerificationKeyOrHashOrFile keyrole -> t m (Hash keyrole)
readVerificationKeyOrHashOrTextEnvFile VerificationKeyOrHashOrFile GenesisDelegateKey
genDelVkOrHashOrFp
    Hash VrfKey
vrfVkHash <-
      ExceptT (FileError InputDecodeError) IO (Hash VrfKey)
-> RIO e (Hash VrfKey)
forall e (m :: * -> *) a.
(HasCallStack, MonadIO m, Show e, Typeable e, Error e) =>
ExceptT e IO a -> m a
fromExceptTCli (ExceptT (FileError InputDecodeError) IO (Hash VrfKey)
 -> RIO e (Hash VrfKey))
-> ExceptT (FileError InputDecodeError) IO (Hash VrfKey)
-> RIO e (Hash VrfKey)
forall a b. (a -> b) -> a -> b
$
        VerificationKeyOrHashOrFile VrfKey
-> ExceptT (FileError InputDecodeError) IO (Hash VrfKey)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) keyrole.
(MonadIOTransError (FileError InputDecodeError) t m, Key keyrole,
 SerialiseAsBech32 (VerificationKey keyrole)) =>
VerificationKeyOrHashOrFile keyrole -> t m (Hash keyrole)
readVerificationKeyOrHashOrFile VerificationKeyOrHashOrFile VrfKey
vrfVkOrHashOrFp

    let req :: GenesisKeyDelegationRequirements era
req = ShelleyToBabbageEra era
-> Hash GenesisKey
-> Hash GenesisDelegateKey
-> Hash VrfKey
-> GenesisKeyDelegationRequirements era
forall era.
ShelleyToBabbageEra era
-> Hash GenesisKey
-> Hash GenesisDelegateKey
-> Hash VrfKey
-> GenesisKeyDelegationRequirements era
GenesisKeyDelegationRequirements ShelleyToBabbageEra era
stb Hash GenesisKey
genesisVkHash Hash GenesisDelegateKey
genesisDelVkHash Hash VrfKey
vrfVkHash
        genKeyDelegCert :: Certificate era
genKeyDelegCert = GenesisKeyDelegationRequirements era -> Certificate era
forall era.
Typeable era =>
GenesisKeyDelegationRequirements era -> Certificate era
makeGenesisKeyDelegationCertificate GenesisKeyDelegationRequirements era
req

    forall e (m :: * -> *) a.
(HasCallStack, MonadIO m, Show e, Typeable e, Error e) =>
IO (Either e a) -> m a
fromEitherIOCli @(FileError ()) (IO (Either (FileError ()) ()) -> RIO e ())
-> IO (Either (FileError ()) ()) -> RIO e ()
forall a b. (a -> b) -> a -> b
$
      File () 'Out -> ByteString -> IO (Either (FileError ()) ())
forall (m :: * -> *) content e.
MonadIO m =>
File content 'Out -> ByteString -> m (Either (FileError e) ())
writeLazyByteStringFile File () 'Out
oFp (ByteString -> IO (Either (FileError ()) ()))
-> ByteString -> IO (Either (FileError ()) ())
forall a b. (a -> b) -> a -> b
$
        ShelleyBasedEra era
-> (ShelleyBasedEraConstraints era => ByteString) -> ByteString
forall era a.
ShelleyBasedEra era -> (ShelleyBasedEraConstraints era => a) -> a
shelleyBasedEraConstraints (ShelleyToBabbageEra era -> ShelleyBasedEra era
forall era. ShelleyToBabbageEra era -> ShelleyBasedEra era
forall a (f :: a -> *) (g :: a -> *) (era :: a).
Convert f g =>
f era -> g era
convert ShelleyToBabbageEra era
stb) ((ShelleyBasedEraConstraints era => ByteString) -> ByteString)
-> (ShelleyBasedEraConstraints era => ByteString) -> ByteString
forall a b. (a -> b) -> a -> b
$
          Maybe TextEnvelopeDescr -> Certificate era -> ByteString
forall a.
HasTextEnvelope a =>
Maybe TextEnvelopeDescr -> a -> ByteString
textEnvelopeToJSON (TextEnvelopeDescr -> Maybe TextEnvelopeDescr
forall a. a -> Maybe a
Just TextEnvelopeDescr
genKeyDelegCertDesc) Certificate era
genKeyDelegCert
   where
    genKeyDelegCertDesc :: TextEnvelopeDescr
    genKeyDelegCertDesc :: TextEnvelopeDescr
genKeyDelegCertDesc = TextEnvelopeDescr
"Genesis Key Delegation Certificate"