{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE LambdaCase #-}

module Cardano.CLI.EraBased.Commands.Genesis
  ( GenesisCmds (..)
  , GenesisCreateCmdArgs (..)
  , GenesisCreateCardanoCmdArgs (..)
  , GenesisCreateStakedCmdArgs (..)
  , GenesisCreateTestNetDataCmdArgs (..)
  , GenesisKeyGenGenesisCmdArgs (..)
  , GenesisKeyGenDelegateCmdArgs (..)
  , GenesisKeyGenUTxOCmdArgs (..)
  , GenesisVerKeyCmdArgs (..)
  , GenesisTxInCmdArgs (..)
  , GenesisAddrCmdArgs (..)
  , renderGenesisCmds
  )
where

import qualified Cardano.Api.Byron as Byron
import qualified Cardano.Api.Experimental as Exp
import           Cardano.Api.Ledger (Coin)
import           Cardano.Api.Shelley

import           Cardano.CLI.Types.Common

import           Data.Text (Text)

data GenesisCmds era
  = GenesisCreate !(GenesisCreateCmdArgs era)
  | GenesisCreateCardano !(GenesisCreateCardanoCmdArgs era)
  | GenesisCreateStaked !(GenesisCreateStakedCmdArgs era)
  | GenesisCreateTestNetData !GenesisCreateTestNetDataCmdArgs
  | GenesisKeyGenGenesis !GenesisKeyGenGenesisCmdArgs
  | GenesisKeyGenDelegate !GenesisKeyGenDelegateCmdArgs
  | GenesisKeyGenUTxO !GenesisKeyGenUTxOCmdArgs
  | GenesisCmdKeyHash !(VerificationKeyFile In)
  | GenesisVerKey !GenesisVerKeyCmdArgs
  | GenesisTxIn !GenesisTxInCmdArgs
  | GenesisAddr !GenesisAddrCmdArgs
  | GenesisHashFile !GenesisFile
  deriving Int -> GenesisCmds era -> ShowS
[GenesisCmds era] -> ShowS
GenesisCmds era -> String
(Int -> GenesisCmds era -> ShowS)
-> (GenesisCmds era -> String)
-> ([GenesisCmds era] -> ShowS)
-> Show (GenesisCmds era)
forall era. Int -> GenesisCmds era -> ShowS
forall era. [GenesisCmds era] -> ShowS
forall era. GenesisCmds era -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall era. Int -> GenesisCmds era -> ShowS
showsPrec :: Int -> GenesisCmds era -> ShowS
$cshow :: forall era. GenesisCmds era -> String
show :: GenesisCmds era -> String
$cshowList :: forall era. [GenesisCmds era] -> ShowS
showList :: [GenesisCmds era] -> ShowS
Show

data GenesisCreateCmdArgs era = GenesisCreateCmdArgs
  { forall era. GenesisCreateCmdArgs era -> ShelleyBasedEra era
eon :: !(ShelleyBasedEra era)
  , forall era. GenesisCreateCmdArgs era -> KeyOutputFormat
keyOutputFormat :: !KeyOutputFormat
  , forall era. GenesisCreateCmdArgs era -> GenesisDir
genesisDir :: !GenesisDir
  , forall era. GenesisCreateCmdArgs era -> Word
numGenesisKeys :: !Word
  , forall era. GenesisCreateCmdArgs era -> Word
numUTxOKeys :: !Word
  , forall era. GenesisCreateCmdArgs era -> Maybe SystemStart
mSystemStart :: !(Maybe SystemStart)
  , forall era. GenesisCreateCmdArgs era -> Maybe Coin
mSupply :: !(Maybe Coin)
  , forall era. GenesisCreateCmdArgs era -> NetworkId
network :: !NetworkId
  }
  deriving Int -> GenesisCreateCmdArgs era -> ShowS
[GenesisCreateCmdArgs era] -> ShowS
GenesisCreateCmdArgs era -> String
(Int -> GenesisCreateCmdArgs era -> ShowS)
-> (GenesisCreateCmdArgs era -> String)
-> ([GenesisCreateCmdArgs era] -> ShowS)
-> Show (GenesisCreateCmdArgs era)
forall era. Int -> GenesisCreateCmdArgs era -> ShowS
forall era. [GenesisCreateCmdArgs era] -> ShowS
forall era. GenesisCreateCmdArgs era -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall era. Int -> GenesisCreateCmdArgs era -> ShowS
showsPrec :: Int -> GenesisCreateCmdArgs era -> ShowS
$cshow :: forall era. GenesisCreateCmdArgs era -> String
show :: GenesisCreateCmdArgs era -> String
$cshowList :: forall era. [GenesisCreateCmdArgs era] -> ShowS
showList :: [GenesisCreateCmdArgs era] -> ShowS
Show

data GenesisCreateCardanoCmdArgs era = GenesisCreateCardanoCmdArgs
  { forall era. GenesisCreateCardanoCmdArgs era -> ShelleyBasedEra era
eon :: !(ShelleyBasedEra era)
  , forall era. GenesisCreateCardanoCmdArgs era -> GenesisDir
genesisDir :: !GenesisDir
  , forall era. GenesisCreateCardanoCmdArgs era -> Word
numGenesisKeys :: !Word
  , forall era. GenesisCreateCardanoCmdArgs era -> Word
numUTxOKeys :: !Word
  , forall era. GenesisCreateCardanoCmdArgs era -> Maybe SystemStart
mSystemStart :: !(Maybe SystemStart)
  , forall era. GenesisCreateCardanoCmdArgs era -> Maybe Coin
mSupply :: !(Maybe Coin)
  , forall era. GenesisCreateCardanoCmdArgs era -> BlockCount
security :: !Byron.BlockCount
  , forall era. GenesisCreateCardanoCmdArgs era -> Word
slotLength :: !Word
  , forall era. GenesisCreateCardanoCmdArgs era -> Rational
slotCoeff :: !Rational
  , forall era. GenesisCreateCardanoCmdArgs era -> NetworkId
network :: !NetworkId
  , forall era. GenesisCreateCardanoCmdArgs era -> String
byronGenesisTemplate :: !FilePath
  , forall era. GenesisCreateCardanoCmdArgs era -> String
shelleyGenesisTemplate :: !FilePath
  , forall era. GenesisCreateCardanoCmdArgs era -> String
alonzoGenesisTemplate :: !FilePath
  , forall era. GenesisCreateCardanoCmdArgs era -> String
conwayGenesisTemplate :: !FilePath
  , forall era. GenesisCreateCardanoCmdArgs era -> Maybe String
mNodeConfigTemplate :: !(Maybe FilePath)
  }
  deriving Int -> GenesisCreateCardanoCmdArgs era -> ShowS
[GenesisCreateCardanoCmdArgs era] -> ShowS
GenesisCreateCardanoCmdArgs era -> String
(Int -> GenesisCreateCardanoCmdArgs era -> ShowS)
-> (GenesisCreateCardanoCmdArgs era -> String)
-> ([GenesisCreateCardanoCmdArgs era] -> ShowS)
-> Show (GenesisCreateCardanoCmdArgs era)
forall era. Int -> GenesisCreateCardanoCmdArgs era -> ShowS
forall era. [GenesisCreateCardanoCmdArgs era] -> ShowS
forall era. GenesisCreateCardanoCmdArgs era -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall era. Int -> GenesisCreateCardanoCmdArgs era -> ShowS
showsPrec :: Int -> GenesisCreateCardanoCmdArgs era -> ShowS
$cshow :: forall era. GenesisCreateCardanoCmdArgs era -> String
show :: GenesisCreateCardanoCmdArgs era -> String
$cshowList :: forall era. [GenesisCreateCardanoCmdArgs era] -> ShowS
showList :: [GenesisCreateCardanoCmdArgs era] -> ShowS
Show

data GenesisCreateStakedCmdArgs era = GenesisCreateStakedCmdArgs
  { forall era. GenesisCreateStakedCmdArgs era -> ShelleyBasedEra era
eon :: !(ShelleyBasedEra era)
  , forall era. GenesisCreateStakedCmdArgs era -> KeyOutputFormat
keyOutputFormat :: !KeyOutputFormat
  , forall era. GenesisCreateStakedCmdArgs era -> GenesisDir
genesisDir :: !GenesisDir
  , forall era. GenesisCreateStakedCmdArgs era -> Word
numGenesisKeys :: !Word
  , forall era. GenesisCreateStakedCmdArgs era -> Word
numUTxOKeys :: !Word
  , forall era. GenesisCreateStakedCmdArgs era -> Word
numPools :: !Word
  , forall era. GenesisCreateStakedCmdArgs era -> Word
numStakeDelegators :: !Word
  , forall era. GenesisCreateStakedCmdArgs era -> Maybe SystemStart
mSystemStart :: !(Maybe SystemStart)
  , forall era. GenesisCreateStakedCmdArgs era -> Maybe Coin
mNonDelegatedSupply :: !(Maybe Coin)
  , forall era. GenesisCreateStakedCmdArgs era -> Coin
delegatedSupply :: !Coin
  , forall era. GenesisCreateStakedCmdArgs era -> NetworkId
network :: !NetworkId
  , forall era. GenesisCreateStakedCmdArgs era -> Word
numBulkPoolCredFiles :: !Word
  , forall era. GenesisCreateStakedCmdArgs era -> Word
numBulkPoolsPerFile :: !Word
  , forall era. GenesisCreateStakedCmdArgs era -> Word
numStuffedUtxo :: !Word
  , forall era. GenesisCreateStakedCmdArgs era -> Maybe String
mStakePoolRelaySpecFile :: !(Maybe FilePath)
  -- ^ Relay specification filepath
  }
  deriving Int -> GenesisCreateStakedCmdArgs era -> ShowS
[GenesisCreateStakedCmdArgs era] -> ShowS
GenesisCreateStakedCmdArgs era -> String
(Int -> GenesisCreateStakedCmdArgs era -> ShowS)
-> (GenesisCreateStakedCmdArgs era -> String)
-> ([GenesisCreateStakedCmdArgs era] -> ShowS)
-> Show (GenesisCreateStakedCmdArgs era)
forall era. Int -> GenesisCreateStakedCmdArgs era -> ShowS
forall era. [GenesisCreateStakedCmdArgs era] -> ShowS
forall era. GenesisCreateStakedCmdArgs era -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall era. Int -> GenesisCreateStakedCmdArgs era -> ShowS
showsPrec :: Int -> GenesisCreateStakedCmdArgs era -> ShowS
$cshow :: forall era. GenesisCreateStakedCmdArgs era -> String
show :: GenesisCreateStakedCmdArgs era -> String
$cshowList :: forall era. [GenesisCreateStakedCmdArgs era] -> ShowS
showList :: [GenesisCreateStakedCmdArgs era] -> ShowS
Show

-- TODO This existential type parameter should become a regular type parameter
-- when we parameterize the parent type by the experimental era API.
data GenesisCreateTestNetDataCmdArgs = forall era. GenesisCreateTestNetDataCmdArgs
  { ()
eon :: !(Exp.Era era)
  , GenesisCreateTestNetDataCmdArgs -> Maybe String
specShelley :: !(Maybe FilePath)
  -- ^ Path to the @genesis-shelley@ file to use. If unspecified, a default one will be used.
  , GenesisCreateTestNetDataCmdArgs -> Maybe String
specAlonzo :: !(Maybe FilePath)
  -- ^ Path to the @genesis-alonzo@ file to use. If unspecified, a default one will be used.
  , GenesisCreateTestNetDataCmdArgs -> Maybe String
specConway :: !(Maybe FilePath)
  -- ^ Path to the @genesis-conway@ file to use. If unspecified, a default one will be used.
  , GenesisCreateTestNetDataCmdArgs -> Word
numGenesisKeys :: !Word
  -- ^ The number of genesis keys credentials to create and write to disk.
  , GenesisCreateTestNetDataCmdArgs -> Word
numPools :: !Word
  -- ^ The number of stake pools credentials to create and write to disk.
  , GenesisCreateTestNetDataCmdArgs -> StakeDelegators
stakeDelegators :: !StakeDelegators
  -- ^ The number of members of the constitutional committee
  , GenesisCreateTestNetDataCmdArgs -> Word
numCommitteeKeys :: !Word
  -- ^ The number of delegators to pools and DReps to create.
  , GenesisCreateTestNetDataCmdArgs -> DRepCredentials
numDRepKeys :: !DRepCredentials
  -- ^ The number of DRep keys to create. They are registered and get delegated to by stake delegators
  , GenesisCreateTestNetDataCmdArgs -> Word
numStuffedUtxo :: !Word
  -- ^ The number of UTxO accounts to make. They are "stuffed" because the credentials are not written to disk.
  , GenesisCreateTestNetDataCmdArgs -> Word
numUtxoKeys :: !Word
  -- ^ The number of UTxO credentials to create and write to disk.
  , GenesisCreateTestNetDataCmdArgs -> Maybe Coin
totalSupply :: !(Maybe Coin)
  -- ^ The total number of Lovelace
  , GenesisCreateTestNetDataCmdArgs -> Maybe Coin
delegatedSupply :: !(Maybe Coin)
  -- ^ The number of Lovelace being delegated
  , GenesisCreateTestNetDataCmdArgs -> Maybe NetworkId
networkId :: !(Maybe NetworkId)
  -- ^ The network ID to use. Overrides the network id supplied in the spec file.
  , GenesisCreateTestNetDataCmdArgs -> Maybe String
relays :: !(Maybe FilePath)
  -- ^ Filepath of the specification of relays
  , GenesisCreateTestNetDataCmdArgs -> Maybe SystemStart
systemStart :: !(Maybe SystemStart)
  -- ^ The genesis start time.
  , GenesisCreateTestNetDataCmdArgs -> String
outputDir :: !FilePath
  -- ^ Directory where to write credentials and files.
  }

instance Show GenesisCreateTestNetDataCmdArgs where
  show :: GenesisCreateTestNetDataCmdArgs -> String
show GenesisCreateTestNetDataCmdArgs
_ = String
"GenesisCreateTestNetDataCmdArgs"

data GenesisKeyGenGenesisCmdArgs = GenesisKeyGenGenesisCmdArgs
  { GenesisKeyGenGenesisCmdArgs -> VerificationKeyFile 'Out
verificationKeyPath :: !(VerificationKeyFile Out)
  , GenesisKeyGenGenesisCmdArgs -> SigningKeyFile 'Out
signingKeyPath :: !(SigningKeyFile Out)
  }
  deriving Int -> GenesisKeyGenGenesisCmdArgs -> ShowS
[GenesisKeyGenGenesisCmdArgs] -> ShowS
GenesisKeyGenGenesisCmdArgs -> String
(Int -> GenesisKeyGenGenesisCmdArgs -> ShowS)
-> (GenesisKeyGenGenesisCmdArgs -> String)
-> ([GenesisKeyGenGenesisCmdArgs] -> ShowS)
-> Show GenesisKeyGenGenesisCmdArgs
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> GenesisKeyGenGenesisCmdArgs -> ShowS
showsPrec :: Int -> GenesisKeyGenGenesisCmdArgs -> ShowS
$cshow :: GenesisKeyGenGenesisCmdArgs -> String
show :: GenesisKeyGenGenesisCmdArgs -> String
$cshowList :: [GenesisKeyGenGenesisCmdArgs] -> ShowS
showList :: [GenesisKeyGenGenesisCmdArgs] -> ShowS
Show

data GenesisKeyGenDelegateCmdArgs = GenesisKeyGenDelegateCmdArgs
  { GenesisKeyGenDelegateCmdArgs -> VerificationKeyFile 'Out
verificationKeyPath :: !(VerificationKeyFile Out)
  , GenesisKeyGenDelegateCmdArgs -> SigningKeyFile 'Out
signingKeyPath :: !(SigningKeyFile Out)
  , GenesisKeyGenDelegateCmdArgs -> OpCertCounterFile 'Out
opCertCounterPath :: !(OpCertCounterFile Out)
  }
  deriving Int -> GenesisKeyGenDelegateCmdArgs -> ShowS
[GenesisKeyGenDelegateCmdArgs] -> ShowS
GenesisKeyGenDelegateCmdArgs -> String
(Int -> GenesisKeyGenDelegateCmdArgs -> ShowS)
-> (GenesisKeyGenDelegateCmdArgs -> String)
-> ([GenesisKeyGenDelegateCmdArgs] -> ShowS)
-> Show GenesisKeyGenDelegateCmdArgs
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> GenesisKeyGenDelegateCmdArgs -> ShowS
showsPrec :: Int -> GenesisKeyGenDelegateCmdArgs -> ShowS
$cshow :: GenesisKeyGenDelegateCmdArgs -> String
show :: GenesisKeyGenDelegateCmdArgs -> String
$cshowList :: [GenesisKeyGenDelegateCmdArgs] -> ShowS
showList :: [GenesisKeyGenDelegateCmdArgs] -> ShowS
Show

data GenesisKeyGenUTxOCmdArgs = GenesisKeyGenUTxOCmdArgs
  { GenesisKeyGenUTxOCmdArgs -> VerificationKeyFile 'Out
verificationKeyPath :: !(VerificationKeyFile Out)
  , GenesisKeyGenUTxOCmdArgs -> SigningKeyFile 'Out
signingKeyPath :: !(SigningKeyFile Out)
  }
  deriving Int -> GenesisKeyGenUTxOCmdArgs -> ShowS
[GenesisKeyGenUTxOCmdArgs] -> ShowS
GenesisKeyGenUTxOCmdArgs -> String
(Int -> GenesisKeyGenUTxOCmdArgs -> ShowS)
-> (GenesisKeyGenUTxOCmdArgs -> String)
-> ([GenesisKeyGenUTxOCmdArgs] -> ShowS)
-> Show GenesisKeyGenUTxOCmdArgs
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> GenesisKeyGenUTxOCmdArgs -> ShowS
showsPrec :: Int -> GenesisKeyGenUTxOCmdArgs -> ShowS
$cshow :: GenesisKeyGenUTxOCmdArgs -> String
show :: GenesisKeyGenUTxOCmdArgs -> String
$cshowList :: [GenesisKeyGenUTxOCmdArgs] -> ShowS
showList :: [GenesisKeyGenUTxOCmdArgs] -> ShowS
Show

data GenesisVerKeyCmdArgs = GenesisVerKeyCmdArgs
  { GenesisVerKeyCmdArgs -> VerificationKeyFile 'Out
verificationKeyPath :: !(VerificationKeyFile Out)
  , GenesisVerKeyCmdArgs -> SigningKeyFile 'In
signingKeyPath :: !(SigningKeyFile In)
  }
  deriving Int -> GenesisVerKeyCmdArgs -> ShowS
[GenesisVerKeyCmdArgs] -> ShowS
GenesisVerKeyCmdArgs -> String
(Int -> GenesisVerKeyCmdArgs -> ShowS)
-> (GenesisVerKeyCmdArgs -> String)
-> ([GenesisVerKeyCmdArgs] -> ShowS)
-> Show GenesisVerKeyCmdArgs
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> GenesisVerKeyCmdArgs -> ShowS
showsPrec :: Int -> GenesisVerKeyCmdArgs -> ShowS
$cshow :: GenesisVerKeyCmdArgs -> String
show :: GenesisVerKeyCmdArgs -> String
$cshowList :: [GenesisVerKeyCmdArgs] -> ShowS
showList :: [GenesisVerKeyCmdArgs] -> ShowS
Show

data GenesisTxInCmdArgs = GenesisTxInCmdArgs
  { GenesisTxInCmdArgs -> VerificationKeyFile 'In
verificationKeyPath :: !(VerificationKeyFile In)
  , GenesisTxInCmdArgs -> NetworkId
network :: !NetworkId
  , GenesisTxInCmdArgs -> Maybe (File () 'Out)
mOutFile :: !(Maybe (File () Out))
  }
  deriving Int -> GenesisTxInCmdArgs -> ShowS
[GenesisTxInCmdArgs] -> ShowS
GenesisTxInCmdArgs -> String
(Int -> GenesisTxInCmdArgs -> ShowS)
-> (GenesisTxInCmdArgs -> String)
-> ([GenesisTxInCmdArgs] -> ShowS)
-> Show GenesisTxInCmdArgs
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> GenesisTxInCmdArgs -> ShowS
showsPrec :: Int -> GenesisTxInCmdArgs -> ShowS
$cshow :: GenesisTxInCmdArgs -> String
show :: GenesisTxInCmdArgs -> String
$cshowList :: [GenesisTxInCmdArgs] -> ShowS
showList :: [GenesisTxInCmdArgs] -> ShowS
Show

data GenesisAddrCmdArgs = GenesisAddrCmdArgs
  { GenesisAddrCmdArgs -> VerificationKeyFile 'In
verificationKeyPath :: !(VerificationKeyFile In)
  , GenesisAddrCmdArgs -> NetworkId
network :: !NetworkId
  , GenesisAddrCmdArgs -> Maybe (File () 'Out)
mOutFile :: !(Maybe (File () Out))
  }
  deriving Int -> GenesisAddrCmdArgs -> ShowS
[GenesisAddrCmdArgs] -> ShowS
GenesisAddrCmdArgs -> String
(Int -> GenesisAddrCmdArgs -> ShowS)
-> (GenesisAddrCmdArgs -> String)
-> ([GenesisAddrCmdArgs] -> ShowS)
-> Show GenesisAddrCmdArgs
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> GenesisAddrCmdArgs -> ShowS
showsPrec :: Int -> GenesisAddrCmdArgs -> ShowS
$cshow :: GenesisAddrCmdArgs -> String
show :: GenesisAddrCmdArgs -> String
$cshowList :: [GenesisAddrCmdArgs] -> ShowS
showList :: [GenesisAddrCmdArgs] -> ShowS
Show

renderGenesisCmds :: GenesisCmds era -> Text
renderGenesisCmds :: forall era. GenesisCmds era -> Text
renderGenesisCmds = \case
  GenesisCreate{} ->
    Text
"genesis create"
  GenesisCreateCardano{} ->
    Text
"genesis create-cardano"
  GenesisCreateStaked{} ->
    Text
"genesis create-staked"
  GenesisCreateTestNetData{} ->
    Text
"genesis create-testnet-data"
  GenesisKeyGenGenesis{} ->
    Text
"genesis key-gen-genesis"
  GenesisKeyGenDelegate{} ->
    Text
"genesis key-gen-delegate"
  GenesisKeyGenUTxO{} ->
    Text
"genesis key-gen-utxo"
  GenesisCmdKeyHash{} ->
    Text
"genesis key-hash"
  GenesisVerKey{} ->
    Text
"genesis get-ver-key"
  GenesisTxIn{} ->
    Text
"genesis initial-txin"
  GenesisAddr{} ->
    Text
"genesis initial-addr"
  GenesisHashFile{} ->
    Text
"genesis hash"