{-# LANGUAGE LambdaCase #-}

module Cardano.CLI.Types.Errors.RegistrationError
  ( RegistrationError (..)
  )
where

import           Cardano.Api
import qualified Cardano.Api.Ledger as L

import           Cardano.CLI.Types.Errors.HashCmdError (FetchURLError, HashCheckError)
import           Cardano.CLI.Types.Errors.StakeAddressRegistrationError
import           Cardano.CLI.Types.Errors.StakeCredentialError

import           Control.Exception (displayException)

data RegistrationError
  = RegistrationReadError !(FileError InputDecodeError)
  | RegistrationWriteFileError !(FileError ())
  | RegistrationStakeCredentialError !StakeCredentialError
  | RegistrationStakeError !StakeAddressRegistrationError
  | RegistrationMismatchedDRepMetadataHashError
      !(L.SafeHash L.StandardCrypto L.AnchorData)
      -- ^ The expected DRep metadata hash.
      !(L.SafeHash L.StandardCrypto L.AnchorData)
      -- ^ The actual DRep metadata hash.
  | RegistrationFetchURLError !FetchURLError
  | RegistrationDRepHashCheckError !HashCheckError
  deriving Int -> RegistrationError -> ShowS
[RegistrationError] -> ShowS
RegistrationError -> String
(Int -> RegistrationError -> ShowS)
-> (RegistrationError -> String)
-> ([RegistrationError] -> ShowS)
-> Show RegistrationError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> RegistrationError -> ShowS
showsPrec :: Int -> RegistrationError -> ShowS
$cshow :: RegistrationError -> String
show :: RegistrationError -> String
$cshowList :: [RegistrationError] -> ShowS
showList :: [RegistrationError] -> ShowS
Show

instance Error RegistrationError where
  prettyError :: forall ann. RegistrationError -> Doc ann
prettyError = \case
    RegistrationReadError FileError InputDecodeError
e ->
      Doc ann
"Cannot read registration certificate: " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> FileError InputDecodeError -> Doc ann
forall e ann. Error e => e -> Doc ann
forall ann. FileError InputDecodeError -> Doc ann
prettyError FileError InputDecodeError
e
    RegistrationWriteFileError FileError ()
e ->
      Doc ann
"Cannot write registration certificate: " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> FileError () -> Doc ann
forall e ann. Error e => e -> Doc ann
forall ann. FileError () -> Doc ann
prettyError FileError ()
e
    RegistrationStakeCredentialError StakeCredentialError
e ->
      Doc ann
"Cannot read stake credential: " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> StakeCredentialError -> Doc ann
forall e ann. Error e => e -> Doc ann
forall ann. StakeCredentialError -> Doc ann
prettyError StakeCredentialError
e
    RegistrationStakeError StakeAddressRegistrationError
e ->
      Doc ann
"Stake address registation error: " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> StakeAddressRegistrationError -> Doc ann
forall e ann. Error e => e -> Doc ann
forall ann. StakeAddressRegistrationError -> Doc ann
prettyError StakeAddressRegistrationError
e
    RegistrationMismatchedDRepMetadataHashError SafeHash StandardCrypto AnchorData
expectedHash SafeHash StandardCrypto AnchorData
actualHash ->
      Doc ann
"DRep metadata Hashes do not match!"
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
"\nExpected:"
          Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> String -> Doc ann
forall ann. String -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty (Hash Blake2b_256 AnchorData -> String
forall a. Show a => a -> String
show (SafeHash StandardCrypto AnchorData
-> Hash (HASH StandardCrypto) AnchorData
forall c i. SafeHash c i -> Hash (HASH c) i
L.extractHash SafeHash StandardCrypto AnchorData
expectedHash))
        Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
"\n  Actual:"
          Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> String -> Doc ann
forall ann. String -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty (Hash Blake2b_256 AnchorData -> String
forall a. Show a => a -> String
show (SafeHash StandardCrypto AnchorData
-> Hash (HASH StandardCrypto) AnchorData
forall c i. SafeHash c i -> Hash (HASH c) i
L.extractHash SafeHash StandardCrypto AnchorData
actualHash))
    RegistrationFetchURLError FetchURLError
fetchErr ->
      Doc ann
"Error while fetching proposal: " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> String -> Doc ann
forall ann. String -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty (FetchURLError -> String
forall e. Exception e => e -> String
displayException FetchURLError
fetchErr)
    RegistrationDRepHashCheckError HashCheckError
hashCheckError ->
      Doc ann
"Error while checking DRep metadata hash: " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> String -> Doc ann
forall ann. String -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty (HashCheckError -> String
forall e. Exception e => e -> String
displayException HashCheckError
hashCheckError)