{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}

-- | Tools for reporting things in readable manner. Used in Rules to implement
--   STS 'renderAssertionViolation' methods, and in Tests.
module Cardano.Ledger.Shelley.Rules.Reports (
  showCred,
  showIR,
  showKeyHash,
  showListy,
  showMap,
  showWithdrawal,
  showSafeHash,
  synopsisCoinMap,
  showTxCerts,
  produceEqualsConsumed,
) where

import Cardano.Ledger.Coin (Coin)
import Cardano.Ledger.Core
import Cardano.Ledger.Credential (Credential (..))
import Cardano.Ledger.Shelley.AdaPots (consumedTxBody, producedTxBody)
import Cardano.Ledger.Shelley.TxBody (RewardAccount (..), Withdrawals (..))
import Cardano.Ledger.State (EraCertState (..), InstantaneousRewards (..), UTxO (..))
import Data.Foldable (fold, toList)
import qualified Data.Map.Strict as Map
import Lens.Micro ((^.))

-- ===============================================
-- Reporting Certificates

showCred :: Credential x -> String
showCred :: forall (x :: KeyRole). Credential x -> String
showCred (ScriptHashObj (ScriptHash Hash ADDRHASH EraIndependentScript
x)) = Hash ADDRHASH EraIndependentScript -> String
forall a. Show a => a -> String
show Hash ADDRHASH EraIndependentScript
x
showCred (KeyHashObj (KeyHash Hash ADDRHASH (VerKeyDSIGN DSIGN)
x)) = Hash ADDRHASH (VerKeyDSIGN DSIGN) -> String
forall a. Show a => a -> String
show Hash ADDRHASH (VerKeyDSIGN DSIGN)
x

showKeyHash :: KeyHash x -> String
showKeyHash :: forall (x :: KeyRole). KeyHash x -> String
showKeyHash (KeyHash Hash ADDRHASH (VerKeyDSIGN DSIGN)
hash) = Int -> String -> String
forall a. Int -> [a] -> [a]
take Int
10 (Hash ADDRHASH (VerKeyDSIGN DSIGN) -> String
forall a. Show a => a -> String
show Hash ADDRHASH (VerKeyDSIGN DSIGN)
hash)

showCerts :: Show (TxCert era) => [TxCert era] -> String
showCerts :: forall era. Show (TxCert era) => [TxCert era] -> String
showCerts [TxCert era]
certs = [String] -> String
unlines ((TxCert era -> String) -> [TxCert era] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map ((String
"  " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String)
-> (TxCert era -> String) -> TxCert era -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TxCert era -> String
forall a. Show a => a -> String
show) [TxCert era]
certs)

showTxCerts :: EraTxBody era => TxBody era -> String
showTxCerts :: forall era. EraTxBody era => TxBody era -> String
showTxCerts TxBody era
txb = [TxCert era] -> String
forall era. Show (TxCert era) => [TxCert era] -> String
showCerts (StrictSeq (TxCert era) -> [TxCert era]
forall a. StrictSeq a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (TxBody era
txb TxBody era
-> Getting
     (StrictSeq (TxCert era)) (TxBody era) (StrictSeq (TxCert era))
-> StrictSeq (TxCert era)
forall s a. s -> Getting a s a -> a
^. Getting
  (StrictSeq (TxCert era)) (TxBody era) (StrictSeq (TxCert era))
forall era.
EraTxBody era =>
Lens' (TxBody era) (StrictSeq (TxCert era))
Lens' (TxBody era) (StrictSeq (TxCert era))
certsTxBodyL))

-- | Display a synopsis of a map to Coin
synopsisCoinMap :: Maybe (Map.Map k Coin) -> String
synopsisCoinMap :: forall k. Maybe (Map k Coin) -> String
synopsisCoinMap (Just Map k Coin
m) = String
"Count = " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Map k Coin -> Int
forall k a. Map k a -> Int
Map.size Map k Coin
m) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
",  total = " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Coin -> String
forall a. Show a => a -> String
show (Map k Coin -> Coin
forall m. Monoid m => Map k m -> m
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold Map k Coin
m)
synopsisCoinMap Maybe (Map k Coin)
Nothing = String
"SYNOPSIS NOTHING"

-- ===============================================
-- Printing Produced == Consumed

produceEqualsConsumed ::
  (EraTxBody era, EraCertState era) =>
  PParams era ->
  CertState era ->
  UTxO era ->
  TxBody era ->
  String
produceEqualsConsumed :: forall era.
(EraTxBody era, EraCertState era) =>
PParams era -> CertState era -> UTxO era -> TxBody era -> String
produceEqualsConsumed PParams era
pp CertState era
dpstate UTxO era
utxo TxBody era
txb =
  let consumedValue :: Consumed
consumedValue = TxBody era -> PParams era -> CertState era -> UTxO era -> Consumed
forall era.
(EraTxBody era, EraCertState era) =>
TxBody era -> PParams era -> CertState era -> UTxO era -> Consumed
consumedTxBody TxBody era
txb PParams era
pp CertState era
dpstate UTxO era
utxo
      producedValue :: Produced
producedValue = TxBody era -> PParams era -> CertState era -> Produced
forall era.
(EraTxBody era, EraCertState era) =>
TxBody era -> PParams era -> CertState era -> Produced
producedTxBody TxBody era
txb PParams era
pp CertState era
dpstate
   in ( String
"\n (Produce = Consumed) Report\n  certificates\n"
          String -> String -> String
forall a. [a] -> [a] -> [a]
++ TxBody era -> String
forall era. EraTxBody era => TxBody era -> String
showTxCerts TxBody era
txb
          String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n  withdrawals "
          String -> String -> String
forall a. [a] -> [a] -> [a]
++ Coin -> String
forall a. Show a => a -> String
show (Map RewardAccount Coin -> Coin
forall m. Monoid m => Map RewardAccount m -> m
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold (Map RewardAccount Coin -> Coin)
-> (Withdrawals -> Map RewardAccount Coin) -> Withdrawals -> Coin
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Withdrawals -> Map RewardAccount Coin
unWithdrawals (Withdrawals -> Coin) -> Withdrawals -> Coin
forall a b. (a -> b) -> a -> b
$ TxBody era
txb TxBody era
-> Getting Withdrawals (TxBody era) Withdrawals -> Withdrawals
forall s a. s -> Getting a s a -> a
^. Getting Withdrawals (TxBody era) Withdrawals
forall era. EraTxBody era => Lens' (TxBody era) Withdrawals
Lens' (TxBody era) Withdrawals
withdrawalsTxBodyL)
          String -> String -> String
forall a. [a] -> [a] -> [a]
++ Produced -> String
forall a. Show a => a -> String
show Produced
producedValue
          String -> String -> String
forall a. [a] -> [a] -> [a]
++ Consumed -> String
forall a. Show a => a -> String
show Consumed
consumedValue
      )

-- ========================

showMap :: (t1 -> [Char]) -> (t2 -> [Char]) -> Map.Map t1 t2 -> String
showMap :: forall t1 t2.
(t1 -> String) -> (t2 -> String) -> Map t1 t2 -> String
showMap t1 -> String
showKey t2 -> String
showVal Map t1 t2
m = [String] -> String
unlines (((t1, t2) -> String) -> [(t1, t2)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (t1, t2) -> String
showpair (Map t1 t2 -> [(t1, t2)]
forall k a. Map k a -> [(k, a)]
Map.toList Map t1 t2
m))
  where
    showpair :: (t1, t2) -> String
showpair (t1
key, t2
val) = t1 -> String
showKey t1
key String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" -> " String -> String -> String
forall a. [a] -> [a] -> [a]
++ t2 -> String
showVal t2
val

showListy :: Foldable t => (a -> String) -> t a -> String
showListy :: forall (t :: * -> *) a.
Foldable t =>
(a -> String) -> t a -> String
showListy a -> String
showElem t a
list = [String] -> String
unlines ((a -> String) -> [a] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map a -> String
showElem (t a -> [a]
forall a. t a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList t a
list))

showRewardAcct :: RewardAccount -> [Char]
showRewardAcct :: RewardAccount -> String
showRewardAcct (RewardAccount {raNetwork :: RewardAccount -> Network
raNetwork = Network
network, raCredential :: RewardAccount -> Credential 'Staking
raCredential = Credential 'Staking
cred}) =
  Network -> String
forall a. Show a => a -> String
show Network
network String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Credential 'Staking -> String
forall (x :: KeyRole). Credential x -> String
showCred Credential 'Staking
cred

showWithdrawal :: Withdrawals -> String
showWithdrawal :: Withdrawals -> String
showWithdrawal (Withdrawals Map RewardAccount Coin
m) = (RewardAccount -> String)
-> (Coin -> String) -> Map RewardAccount Coin -> String
forall t1 t2.
(t1 -> String) -> (t2 -> String) -> Map t1 t2 -> String
showMap ((String
"   " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String)
-> (RewardAccount -> String) -> RewardAccount -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RewardAccount -> String
showRewardAcct) Coin -> String
forall a. Show a => a -> String
show Map RewardAccount Coin
m

showIR :: InstantaneousRewards -> String
showIR :: InstantaneousRewards -> String
showIR (InstantaneousRewards Map (Credential 'Staking) Coin
m Map (Credential 'Staking) Coin
n DeltaCoin
x DeltaCoin
y) =
  [String] -> String
unlines
    [ String
"IRReseves " String -> String -> String
forall a. [a] -> [a] -> [a]
++ (Credential 'Staking -> String)
-> (Coin -> String) -> Map (Credential 'Staking) Coin -> String
forall t1 t2.
(t1 -> String) -> (t2 -> String) -> Map t1 t2 -> String
showMap ((String
"   " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String)
-> (Credential 'Staking -> String) -> Credential 'Staking -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String -> String
forall a. Int -> [a] -> [a]
take Int
10 (String -> String)
-> (Credential 'Staking -> String) -> Credential 'Staking -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Credential 'Staking -> String
forall (x :: KeyRole). Credential x -> String
showCred) Coin -> String
forall a. Show a => a -> String
show Map (Credential 'Staking) Coin
m
    , String
"IRTreasury " String -> String -> String
forall a. [a] -> [a] -> [a]
++ (Credential 'Staking -> String)
-> (Coin -> String) -> Map (Credential 'Staking) Coin -> String
forall t1 t2.
(t1 -> String) -> (t2 -> String) -> Map t1 t2 -> String
showMap ((String
"   " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String)
-> (Credential 'Staking -> String) -> Credential 'Staking -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String -> String
forall a. Int -> [a] -> [a]
take Int
10 (String -> String)
-> (Credential 'Staking -> String) -> Credential 'Staking -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Credential 'Staking -> String
forall (x :: KeyRole). Credential x -> String
showCred) Coin -> String
forall a. Show a => a -> String
show Map (Credential 'Staking) Coin
n
    , String
"DeltaReserves " String -> String -> String
forall a. [a] -> [a] -> [a]
++ DeltaCoin -> String
forall a. Show a => a -> String
show DeltaCoin
x
    , String
"DeltaTreasury " String -> String -> String
forall a. [a] -> [a] -> [a]
++ DeltaCoin -> String
forall a. Show a => a -> String
show DeltaCoin
y
    ]

showSafeHash :: SafeHash i -> String
showSafeHash :: forall i. SafeHash i -> String
showSafeHash SafeHash i
x = Int -> String -> String
forall a. Int -> [a] -> [a]
take Int
12 (Hash HASH i -> String
forall a. Show a => a -> String
show (SafeHash i -> Hash HASH i
forall i. SafeHash i -> Hash HASH i
extractHash SafeHash i
x))