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

module Cardano.CLI.Commands.Key
  ( KeyCmds (..)
  , KeyVerificationKeyCmdArgs (..)
  , KeyNonExtendedKeyCmdArgs (..)
  , KeyConvertByronKeyCmdArgs (..)
  , KeyConvertByronGenesisVKeyCmdArgs (..)
  , KeyConvertITNKeyCmdArgs (..)
  , KeyConvertITNExtendedKeyCmdArgs (..)
  , KeyConvertITNBip32KeyCmdArgs (..)
  , KeyConvertCardanoAddressKeyCmdArgs (..)
  , renderKeyCmds
  )
where

import           Cardano.Api.Shelley

import           Cardano.CLI.Types.Common

import           Data.Text (Text)

data KeyCmds
  = KeyVerificationKeyCmd !KeyVerificationKeyCmdArgs
  | KeyNonExtendedKeyCmd !KeyNonExtendedKeyCmdArgs
  | 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

-- | 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"
  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"