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

module Cardano.CLI.EraIndependent.Key.Command
  ( KeyCmds (..)
  , KeyVerificationKeyCmdArgs (..)
  , KeyNonExtendedKeyCmdArgs (..)
  , KeyGenerateMnemonicCmdArgs (..)
  , KeyExtendedSigningKeyFromMnemonicArgs (..)
  , ExtendedSigningType (..)
  , MnemonicSource (..)
  , KeyConvertByronKeyCmdArgs (..)
  , KeyConvertByronGenesisVKeyCmdArgs (..)
  , KeyConvertITNKeyCmdArgs (..)
  , KeyConvertITNExtendedKeyCmdArgs (..)
  , KeyConvertITNBip32KeyCmdArgs (..)
  , KeyConvertCardanoAddressKeyCmdArgs (..)
  , renderKeyCmds
  )
where

import Cardano.Api.Shelley

import Cardano.CLI.Type.Common
import Cardano.Prelude (Word32)

import Data.Text (Text)

data KeyCmds
  = KeyVerificationKeyCmd !KeyVerificationKeyCmdArgs
  | KeyNonExtendedKeyCmd !KeyNonExtendedKeyCmdArgs
  | KeyGenerateMnemonicCmd !KeyGenerateMnemonicCmdArgs
  | KeyExtendedSigningKeyFromMnemonicCmd !KeyExtendedSigningKeyFromMnemonicArgs
  | KeyConvertByronKeyCmd !KeyConvertByronKeyCmdArgs
  | KeyConvertByronGenesisVKeyCmd !KeyConvertByronGenesisVKeyCmdArgs
  | KeyConvertITNKeyCmd !KeyConvertITNKeyCmdArgs
  | KeyConvertITNExtendedKeyCmd !KeyConvertITNExtendedKeyCmdArgs
  | KeyConvertITNBip32KeyCmd !KeyConvertITNBip32KeyCmdArgs
  | KeyConvertCardanoAddressKeyCmd !KeyConvertCardanoAddressKeyCmdArgs
  deriving Int -> KeyCmds -> ShowS
[KeyCmds] -> ShowS
KeyCmds -> String
(Int -> KeyCmds -> ShowS)
-> (KeyCmds -> String) -> ([KeyCmds] -> ShowS) -> Show KeyCmds
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> KeyCmds -> ShowS
showsPrec :: Int -> KeyCmds -> ShowS
$cshow :: KeyCmds -> String
show :: KeyCmds -> String
$cshowList :: [KeyCmds] -> ShowS
showList :: [KeyCmds] -> ShowS
Show

-- | Get a verification key from a signing key. This supports all key types
data KeyVerificationKeyCmdArgs = KeyVerificationKeyCmdArgs
  { KeyVerificationKeyCmdArgs -> SigningKeyFile 'In
skeyFile :: !(SigningKeyFile In)
  -- ^ Input filepath of the signing key
  , KeyVerificationKeyCmdArgs -> VerificationKeyFile 'Out
vkeyFile :: !(VerificationKeyFile Out)
  -- ^ Output filepath of the verification key
  }
  deriving Int -> KeyVerificationKeyCmdArgs -> ShowS
[KeyVerificationKeyCmdArgs] -> ShowS
KeyVerificationKeyCmdArgs -> String
(Int -> KeyVerificationKeyCmdArgs -> ShowS)
-> (KeyVerificationKeyCmdArgs -> String)
-> ([KeyVerificationKeyCmdArgs] -> ShowS)
-> Show KeyVerificationKeyCmdArgs
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> KeyVerificationKeyCmdArgs -> ShowS
showsPrec :: Int -> KeyVerificationKeyCmdArgs -> ShowS
$cshow :: KeyVerificationKeyCmdArgs -> String
show :: KeyVerificationKeyCmdArgs -> String
$cshowList :: [KeyVerificationKeyCmdArgs] -> ShowS
showList :: [KeyVerificationKeyCmdArgs] -> ShowS
Show

-- | Get a non-extended verification key from an extended verification key. This
-- supports all extended key types.
data KeyNonExtendedKeyCmdArgs = KeyNonExtendedKeyCmdArgs
  { KeyNonExtendedKeyCmdArgs -> VerificationKeyFile 'In
extendedVkeyFileIn :: !(VerificationKeyFile In)
  -- ^ Input filepath of the ed25519-bip32 verification key
  , KeyNonExtendedKeyCmdArgs -> VerificationKeyFile 'Out
nonExtendedVkeyFileOut :: !(VerificationKeyFile Out)
  -- ^ Output filepath of the verification key
  }
  deriving Int -> KeyNonExtendedKeyCmdArgs -> ShowS
[KeyNonExtendedKeyCmdArgs] -> ShowS
KeyNonExtendedKeyCmdArgs -> String
(Int -> KeyNonExtendedKeyCmdArgs -> ShowS)
-> (KeyNonExtendedKeyCmdArgs -> String)
-> ([KeyNonExtendedKeyCmdArgs] -> ShowS)
-> Show KeyNonExtendedKeyCmdArgs
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> KeyNonExtendedKeyCmdArgs -> ShowS
showsPrec :: Int -> KeyNonExtendedKeyCmdArgs -> ShowS
$cshow :: KeyNonExtendedKeyCmdArgs -> String
show :: KeyNonExtendedKeyCmdArgs -> String
$cshowList :: [KeyNonExtendedKeyCmdArgs] -> ShowS
showList :: [KeyNonExtendedKeyCmdArgs] -> ShowS
Show

-- | Generate a mnemonic phrase that can be used to derive signing keys.
data KeyGenerateMnemonicCmdArgs = KeyGenerateMnemonicCmdArgs
  { KeyGenerateMnemonicCmdArgs -> Maybe (File () 'Out)
mnemonicOutputFormat :: !(Maybe (File () Out))
  -- ^ Output format for the mnemonic phrase
  , KeyGenerateMnemonicCmdArgs -> MnemonicSize
mnemonicWords :: !MnemonicSize
  -- ^ Number of mnemonic words to generate it must be one of: 12, 15, 18, 21, or 24.
  }
  deriving Int -> KeyGenerateMnemonicCmdArgs -> ShowS
[KeyGenerateMnemonicCmdArgs] -> ShowS
KeyGenerateMnemonicCmdArgs -> String
(Int -> KeyGenerateMnemonicCmdArgs -> ShowS)
-> (KeyGenerateMnemonicCmdArgs -> String)
-> ([KeyGenerateMnemonicCmdArgs] -> ShowS)
-> Show KeyGenerateMnemonicCmdArgs
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> KeyGenerateMnemonicCmdArgs -> ShowS
showsPrec :: Int -> KeyGenerateMnemonicCmdArgs -> ShowS
$cshow :: KeyGenerateMnemonicCmdArgs -> String
show :: KeyGenerateMnemonicCmdArgs -> String
$cshowList :: [KeyGenerateMnemonicCmdArgs] -> ShowS
showList :: [KeyGenerateMnemonicCmdArgs] -> ShowS
Show

-- | Get an extended signing key from a mnemonic.
data KeyExtendedSigningKeyFromMnemonicArgs = KeyExtendedSigningKeyFromMnemonicArgs
  { KeyExtendedSigningKeyFromMnemonicArgs -> KeyOutputFormat
keyOutputFormat :: !KeyOutputFormat
  , KeyExtendedSigningKeyFromMnemonicArgs -> ExtendedSigningType
derivedExtendedSigningKeyType :: !ExtendedSigningType
  , KeyExtendedSigningKeyFromMnemonicArgs -> Word32
derivationAccountNo :: !Word32
  , KeyExtendedSigningKeyFromMnemonicArgs -> MnemonicSource
mnemonicSource :: !MnemonicSource
  , KeyExtendedSigningKeyFromMnemonicArgs -> SigningKeyFile 'Out
signingKeyFileOut :: !(SigningKeyFile Out)
  }
  deriving Int -> KeyExtendedSigningKeyFromMnemonicArgs -> ShowS
[KeyExtendedSigningKeyFromMnemonicArgs] -> ShowS
KeyExtendedSigningKeyFromMnemonicArgs -> String
(Int -> KeyExtendedSigningKeyFromMnemonicArgs -> ShowS)
-> (KeyExtendedSigningKeyFromMnemonicArgs -> String)
-> ([KeyExtendedSigningKeyFromMnemonicArgs] -> ShowS)
-> Show KeyExtendedSigningKeyFromMnemonicArgs
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> KeyExtendedSigningKeyFromMnemonicArgs -> ShowS
showsPrec :: Int -> KeyExtendedSigningKeyFromMnemonicArgs -> ShowS
$cshow :: KeyExtendedSigningKeyFromMnemonicArgs -> String
show :: KeyExtendedSigningKeyFromMnemonicArgs -> String
$cshowList :: [KeyExtendedSigningKeyFromMnemonicArgs] -> ShowS
showList :: [KeyExtendedSigningKeyFromMnemonicArgs] -> ShowS
Show

data MnemonicSource
  = MnemonicFromFile !(File () In)
  | MnemonicFromInteractivePrompt
  deriving Int -> MnemonicSource -> ShowS
[MnemonicSource] -> ShowS
MnemonicSource -> String
(Int -> MnemonicSource -> ShowS)
-> (MnemonicSource -> String)
-> ([MnemonicSource] -> ShowS)
-> Show MnemonicSource
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MnemonicSource -> ShowS
showsPrec :: Int -> MnemonicSource -> ShowS
$cshow :: MnemonicSource -> String
show :: MnemonicSource -> String
$cshowList :: [MnemonicSource] -> ShowS
showList :: [MnemonicSource] -> ShowS
Show

-- | Type of the key derived from a mnemonic
-- together with the payment key number in the derivation path
-- for cases where it is applicable.
data ExtendedSigningType
  = ExtendedSigningPaymentKey !Word32
  | ExtendedSigningStakeKey !Word32
  | ExtendedSigningDRepKey
  | ExtendedSigningCCColdKey
  | ExtendedSigningCCHotKey
  deriving Int -> ExtendedSigningType -> ShowS
[ExtendedSigningType] -> ShowS
ExtendedSigningType -> String
(Int -> ExtendedSigningType -> ShowS)
-> (ExtendedSigningType -> String)
-> ([ExtendedSigningType] -> ShowS)
-> Show ExtendedSigningType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ExtendedSigningType -> ShowS
showsPrec :: Int -> ExtendedSigningType -> ShowS
$cshow :: ExtendedSigningType -> String
show :: ExtendedSigningType -> String
$cshowList :: [ExtendedSigningType] -> ShowS
showList :: [ExtendedSigningType] -> ShowS
Show

-- | Convert a Byron payment, genesis or genesis delegate key (signing or
-- verification) to a corresponding Shelley-format key.
data KeyConvertByronKeyCmdArgs = KeyConvertByronKeyCmdArgs
  { KeyConvertByronKeyCmdArgs -> Maybe Text
mPassword :: !(Maybe Text)
  -- ^ Password for signing key (if applicable)
  , KeyConvertByronKeyCmdArgs -> ByronKeyType
byronKeyType :: !ByronKeyType
  -- ^ The byron key type of the input file
  , KeyConvertByronKeyCmdArgs -> SomeKeyFile 'In
someKeyFileIn :: !(SomeKeyFile In)
  -- ^ Input file containing the byron key
  , KeyConvertByronKeyCmdArgs -> File () 'Out
someKeyFileOut :: !(File () Out)
  -- ^ The output file to which the Shelley-format key will be written
  }
  deriving Int -> KeyConvertByronKeyCmdArgs -> ShowS
[KeyConvertByronKeyCmdArgs] -> ShowS
KeyConvertByronKeyCmdArgs -> String
(Int -> KeyConvertByronKeyCmdArgs -> ShowS)
-> (KeyConvertByronKeyCmdArgs -> String)
-> ([KeyConvertByronKeyCmdArgs] -> ShowS)
-> Show KeyConvertByronKeyCmdArgs
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> KeyConvertByronKeyCmdArgs -> ShowS
showsPrec :: Int -> KeyConvertByronKeyCmdArgs -> ShowS
$cshow :: KeyConvertByronKeyCmdArgs -> String
show :: KeyConvertByronKeyCmdArgs -> String
$cshowList :: [KeyConvertByronKeyCmdArgs] -> ShowS
showList :: [KeyConvertByronKeyCmdArgs] -> ShowS
Show

-- Convert a Base64-encoded Byron genesis verification key to a Shelley genesis
-- verification key
data KeyConvertByronGenesisVKeyCmdArgs = KeyConvertByronGenesisVKeyCmdArgs
  { KeyConvertByronGenesisVKeyCmdArgs -> VerificationKeyBase64
vkey :: !VerificationKeyBase64
  -- ^ Base64 string for the Byron genesis verification key
  , KeyConvertByronGenesisVKeyCmdArgs -> File () 'Out
vkeyFileOut :: !(File () Out)
  -- ^ The output file
  }
  deriving Int -> KeyConvertByronGenesisVKeyCmdArgs -> ShowS
[KeyConvertByronGenesisVKeyCmdArgs] -> ShowS
KeyConvertByronGenesisVKeyCmdArgs -> String
(Int -> KeyConvertByronGenesisVKeyCmdArgs -> ShowS)
-> (KeyConvertByronGenesisVKeyCmdArgs -> String)
-> ([KeyConvertByronGenesisVKeyCmdArgs] -> ShowS)
-> Show KeyConvertByronGenesisVKeyCmdArgs
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> KeyConvertByronGenesisVKeyCmdArgs -> ShowS
showsPrec :: Int -> KeyConvertByronGenesisVKeyCmdArgs -> ShowS
$cshow :: KeyConvertByronGenesisVKeyCmdArgs -> String
show :: KeyConvertByronGenesisVKeyCmdArgs -> String
$cshowList :: [KeyConvertByronGenesisVKeyCmdArgs] -> ShowS
showList :: [KeyConvertByronGenesisVKeyCmdArgs] -> ShowS
Show

-- | Convert an Incentivized Testnet (ITN) non-extended (Ed25519) signing or
-- verification key to a corresponding Shelley stake key
data KeyConvertITNKeyCmdArgs = KeyConvertITNKeyCmdArgs
  { KeyConvertITNKeyCmdArgs -> SomeKeyFile 'In
itnKeyFile :: !(SomeKeyFile In)
  -- ^ Filepath of the ITN key (signing or verification)
  , KeyConvertITNKeyCmdArgs -> File () 'Out
outFile :: !(File () Out)
  -- ^ The output file
  }
  deriving Int -> KeyConvertITNKeyCmdArgs -> ShowS
[KeyConvertITNKeyCmdArgs] -> ShowS
KeyConvertITNKeyCmdArgs -> String
(Int -> KeyConvertITNKeyCmdArgs -> ShowS)
-> (KeyConvertITNKeyCmdArgs -> String)
-> ([KeyConvertITNKeyCmdArgs] -> ShowS)
-> Show KeyConvertITNKeyCmdArgs
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> KeyConvertITNKeyCmdArgs -> ShowS
showsPrec :: Int -> KeyConvertITNKeyCmdArgs -> ShowS
$cshow :: KeyConvertITNKeyCmdArgs -> String
show :: KeyConvertITNKeyCmdArgs -> String
$cshowList :: [KeyConvertITNKeyCmdArgs] -> ShowS
showList :: [KeyConvertITNKeyCmdArgs] -> ShowS
Show

-- | Convert an Incentivized Testnet (ITN) extended (Ed25519Extended) signing key
-- to a corresponding Shelley stake signing key
data KeyConvertITNExtendedKeyCmdArgs = KeyConvertITNExtendedKeyCmdArgs
  { KeyConvertITNExtendedKeyCmdArgs -> SomeKeyFile 'In
itnPrivKeyFile :: !(SomeKeyFile In)
  -- ^ Filepath of the ITN signing key
  , KeyConvertITNExtendedKeyCmdArgs -> File () 'Out
outFile :: !(File () Out)
  -- ^ The output file
  }
  deriving Int -> KeyConvertITNExtendedKeyCmdArgs -> ShowS
[KeyConvertITNExtendedKeyCmdArgs] -> ShowS
KeyConvertITNExtendedKeyCmdArgs -> String
(Int -> KeyConvertITNExtendedKeyCmdArgs -> ShowS)
-> (KeyConvertITNExtendedKeyCmdArgs -> String)
-> ([KeyConvertITNExtendedKeyCmdArgs] -> ShowS)
-> Show KeyConvertITNExtendedKeyCmdArgs
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> KeyConvertITNExtendedKeyCmdArgs -> ShowS
showsPrec :: Int -> KeyConvertITNExtendedKeyCmdArgs -> ShowS
$cshow :: KeyConvertITNExtendedKeyCmdArgs -> String
show :: KeyConvertITNExtendedKeyCmdArgs -> String
$cshowList :: [KeyConvertITNExtendedKeyCmdArgs] -> ShowS
showList :: [KeyConvertITNExtendedKeyCmdArgs] -> ShowS
Show

-- | Convert an Incentivized Testnet (ITN) BIP32 (Ed25519Bip32) signing key to a
-- corresponding Shelley stake signing key
data KeyConvertITNBip32KeyCmdArgs = KeyConvertITNBip32KeyCmdArgs
  { KeyConvertITNBip32KeyCmdArgs -> SomeKeyFile 'In
itnPrivKeyFile :: !(SomeKeyFile In)
  -- ^ Filepath of the ITN signing key
  , KeyConvertITNBip32KeyCmdArgs -> File () 'Out
outFile :: !(File () Out)
  -- ^ The output file
  }
  deriving Int -> KeyConvertITNBip32KeyCmdArgs -> ShowS
[KeyConvertITNBip32KeyCmdArgs] -> ShowS
KeyConvertITNBip32KeyCmdArgs -> String
(Int -> KeyConvertITNBip32KeyCmdArgs -> ShowS)
-> (KeyConvertITNBip32KeyCmdArgs -> String)
-> ([KeyConvertITNBip32KeyCmdArgs] -> ShowS)
-> Show KeyConvertITNBip32KeyCmdArgs
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> KeyConvertITNBip32KeyCmdArgs -> ShowS
showsPrec :: Int -> KeyConvertITNBip32KeyCmdArgs -> ShowS
$cshow :: KeyConvertITNBip32KeyCmdArgs -> String
show :: KeyConvertITNBip32KeyCmdArgs -> String
$cshowList :: [KeyConvertITNBip32KeyCmdArgs] -> ShowS
showList :: [KeyConvertITNBip32KeyCmdArgs] -> ShowS
Show

-- | Convert a cardano-address extended signing key to a corresponding
-- Shelley-format key
data KeyConvertCardanoAddressKeyCmdArgs = KeyConvertCardanoAddressKeyCmdArgs
  { KeyConvertCardanoAddressKeyCmdArgs -> CardanoAddressKeyType
cardanoAddressKeyType :: !CardanoAddressKeyType
  -- ^ Address key type of th signing key input file
  , KeyConvertCardanoAddressKeyCmdArgs -> SigningKeyFile 'In
skeyFileIn :: !(SigningKeyFile In)
  -- ^ Input filepath of the signing key
  , KeyConvertCardanoAddressKeyCmdArgs -> File () 'Out
skeyFileOut :: !(File () Out)
  -- ^ The output file
  }
  deriving Int -> KeyConvertCardanoAddressKeyCmdArgs -> ShowS
[KeyConvertCardanoAddressKeyCmdArgs] -> ShowS
KeyConvertCardanoAddressKeyCmdArgs -> String
(Int -> KeyConvertCardanoAddressKeyCmdArgs -> ShowS)
-> (KeyConvertCardanoAddressKeyCmdArgs -> String)
-> ([KeyConvertCardanoAddressKeyCmdArgs] -> ShowS)
-> Show KeyConvertCardanoAddressKeyCmdArgs
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> KeyConvertCardanoAddressKeyCmdArgs -> ShowS
showsPrec :: Int -> KeyConvertCardanoAddressKeyCmdArgs -> ShowS
$cshow :: KeyConvertCardanoAddressKeyCmdArgs -> String
show :: KeyConvertCardanoAddressKeyCmdArgs -> String
$cshowList :: [KeyConvertCardanoAddressKeyCmdArgs] -> ShowS
showList :: [KeyConvertCardanoAddressKeyCmdArgs] -> ShowS
Show

renderKeyCmds :: KeyCmds -> Text
renderKeyCmds :: KeyCmds -> Text
renderKeyCmds = \case
  KeyVerificationKeyCmd{} ->
    Text
"key verification-key"
  KeyNonExtendedKeyCmd{} ->
    Text
"key non-extended-key"
  KeyGenerateMnemonicCmd{} ->
    Text
"key generate-mnemonic"
  KeyExtendedSigningKeyFromMnemonicCmd{} ->
    Text
"key from-mnemonic"
  KeyConvertByronKeyCmd{} ->
    Text
"key convert-byron-key"
  KeyConvertByronGenesisVKeyCmd{} ->
    Text
"key convert-byron-genesis-vkey"
  KeyConvertITNKeyCmd{} ->
    Text
"key convert-itn-key"
  KeyConvertITNExtendedKeyCmd{} ->
    Text
"key convert-itn-extended-key"
  KeyConvertITNBip32KeyCmd{} ->
    Text
"key convert-itn-bip32-key"
  KeyConvertCardanoAddressKeyCmd{} ->
    Text
"key convert-cardano-address-key"