{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}

-- |
-- Copyright: © 2022 IOHK
-- License: Apache-2.0
--
-- Defines the 'MinimumUTxO' type and related functions.
--
module Cardano.Wallet.Primitive.Types.MinimumUTxO
    (
    -- * Types
      MinimumUTxO (..)
    , MinimumUTxOForShelleyBasedEra (..)

    -- * Constructor functions
    , minimumUTxONone
    , minimumUTxOConstant
    , minimumUTxOForShelleyBasedEra
    )
    where

import Prelude

import Cardano.Api.Shelley
    ( ShelleyBasedEra, ShelleyLedgerEra, fromLedgerPParams )
import Cardano.Ledger.Core
    ( PParams )
import Cardano.Wallet.Primitive.Types.Coin
    ( Coin )
import Control.DeepSeq
    ( NFData (..) )
import Data.Function
    ( on )
import Fmt
    ( Buildable (..), blockListF )

--------------------------------------------------------------------------------
-- The 'MinimumUTxO' type
--------------------------------------------------------------------------------

-- | Represents a function for computing minimum UTxO values.
--
data MinimumUTxO where
    MinimumUTxONone
        :: MinimumUTxO
        -- ^ Indicates that there is no minimum UTxO value.
    MinimumUTxOConstant
        :: Coin
        -> MinimumUTxO
        -- ^ Indicates a constant minimum UTxO value. This constructor is
        -- useful for writing tests, where we often want to have precise
        -- control over the value that is chosen.
    MinimumUTxOForShelleyBasedEraOf
        :: MinimumUTxOForShelleyBasedEra
        -> MinimumUTxO
        -- ^ Indicates a Shelley-based era-specific minimum UTxO function.

instance Buildable MinimumUTxO where
    build :: MinimumUTxO -> Builder
build = \case
        MinimumUTxO
MinimumUTxONone ->
            Builder
"MinimumUTxONone"
        MinimumUTxOConstant Coin
c -> [Builder] -> Builder
forall (f :: * -> *) a. (Foldable f, Buildable a) => f a -> Builder
blockListF
            [ Builder
"MinimumUTxOConstant"
            , Coin -> Builder
forall p. Buildable p => p -> Builder
build Coin
c
            ]
        MinimumUTxOForShelleyBasedEraOf MinimumUTxOForShelleyBasedEra
m -> [Builder] -> Builder
forall (f :: * -> *) a. (Foldable f, Buildable a) => f a -> Builder
blockListF
            [ Builder
"MinimumUTxOForShelleyBasedEra"
            , MinimumUTxOForShelleyBasedEra -> Builder
forall p. Buildable p => p -> Builder
build MinimumUTxOForShelleyBasedEra
m
            ]

instance Eq MinimumUTxO where
    == :: MinimumUTxO -> MinimumUTxO -> Bool
(==) = String -> String -> Bool
forall a. Eq a => a -> a -> Bool
(==) (String -> String -> Bool)
-> (MinimumUTxO -> String) -> MinimumUTxO -> MinimumUTxO -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` MinimumUTxO -> String
forall a. Show a => a -> String
show

instance NFData MinimumUTxO where
    rnf :: MinimumUTxO -> ()
rnf = \case
        MinimumUTxO
MinimumUTxONone ->
            () -> ()
forall a. NFData a => a -> ()
rnf ()
        MinimumUTxOConstant Coin
c ->
            Coin -> ()
forall a. NFData a => a -> ()
rnf Coin
c
        MinimumUTxOForShelleyBasedEraOf MinimumUTxOForShelleyBasedEra
pp ->
            MinimumUTxOForShelleyBasedEra -> ()
forall a. NFData a => a -> ()
rnf MinimumUTxOForShelleyBasedEra
pp

instance Show MinimumUTxO where
    show :: MinimumUTxO -> String
show = \case
        MinimumUTxO
MinimumUTxONone ->
            String
"MinimumUTxONone"
        MinimumUTxOConstant Coin
c -> [String] -> String
unwords
            [ String
"MinimumUTxOConstant"
            , Coin -> String
forall a. Show a => a -> String
show Coin
c
            ]
        MinimumUTxOForShelleyBasedEraOf MinimumUTxOForShelleyBasedEra
pp -> [String] -> String
unwords
            [ String
"MinimumUTxOForShelleyBasedEra"
            , MinimumUTxOForShelleyBasedEra -> String
forall a. Show a => a -> String
show MinimumUTxOForShelleyBasedEra
pp
            ]

--------------------------------------------------------------------------------
-- The 'MinimumUTxOForShelleyBasedEra' type
--------------------------------------------------------------------------------

-- | Represents a minimum UTxO function that is specific to a Shelley-based era.
--
data MinimumUTxOForShelleyBasedEra where
    MinimumUTxOForShelleyBasedEra
        :: ShelleyBasedEra era
        -> PParams (ShelleyLedgerEra era)
        -> MinimumUTxOForShelleyBasedEra

instance Buildable MinimumUTxOForShelleyBasedEra where
    build :: MinimumUTxOForShelleyBasedEra -> Builder
build (MinimumUTxOForShelleyBasedEra ShelleyBasedEra era
era PParams (ShelleyLedgerEra era)
_) = [String] -> Builder
forall (f :: * -> *) a. (Foldable f, Buildable a) => f a -> Builder
blockListF
        [ String
"MinimumUTxOForShelleyBasedEra"
        , ShelleyBasedEra era -> String
forall a. Show a => a -> String
show ShelleyBasedEra era
era
        ]

instance Eq MinimumUTxOForShelleyBasedEra where
    == :: MinimumUTxOForShelleyBasedEra
-> MinimumUTxOForShelleyBasedEra -> Bool
(==) = String -> String -> Bool
forall a. Eq a => a -> a -> Bool
(==) (String -> String -> Bool)
-> (MinimumUTxOForShelleyBasedEra -> String)
-> MinimumUTxOForShelleyBasedEra
-> MinimumUTxOForShelleyBasedEra
-> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` MinimumUTxOForShelleyBasedEra -> String
forall a. Show a => a -> String
show

instance NFData MinimumUTxOForShelleyBasedEra where
    rnf :: MinimumUTxOForShelleyBasedEra -> ()
rnf (MinimumUTxOForShelleyBasedEra !ShelleyBasedEra era
_ !PParams (ShelleyLedgerEra era)
_) = () -> ()
forall a. NFData a => a -> ()
rnf ()

instance Show MinimumUTxOForShelleyBasedEra where
    show :: MinimumUTxOForShelleyBasedEra -> String
show (MinimumUTxOForShelleyBasedEra ShelleyBasedEra era
era PParams (ShelleyLedgerEra era)
pp) = [String] -> String
unwords
        [ ShelleyBasedEra era -> String
forall a. Show a => a -> String
show ShelleyBasedEra era
era
        , ProtocolParameters -> String
forall a. Show a => a -> String
show (ShelleyBasedEra era
-> PParams (ShelleyLedgerEra era) -> ProtocolParameters
forall era.
ShelleyBasedEra era
-> PParams (ShelleyLedgerEra era) -> ProtocolParameters
fromLedgerPParams ShelleyBasedEra era
era PParams (ShelleyLedgerEra era)
pp)
        ]

--------------------------------------------------------------------------------
-- Constructor functions
--------------------------------------------------------------------------------

minimumUTxONone :: MinimumUTxO
minimumUTxONone :: MinimumUTxO
minimumUTxONone = MinimumUTxO
MinimumUTxONone

minimumUTxOConstant :: Coin -> MinimumUTxO
minimumUTxOConstant :: Coin -> MinimumUTxO
minimumUTxOConstant = Coin -> MinimumUTxO
MinimumUTxOConstant

minimumUTxOForShelleyBasedEra
    :: ShelleyBasedEra era
    -> PParams (ShelleyLedgerEra era)
    -> MinimumUTxO
minimumUTxOForShelleyBasedEra :: ShelleyBasedEra era
-> PParams (ShelleyLedgerEra era) -> MinimumUTxO
minimumUTxOForShelleyBasedEra ShelleyBasedEra era
era PParams (ShelleyLedgerEra era)
pp =
    MinimumUTxOForShelleyBasedEra -> MinimumUTxO
MinimumUTxOForShelleyBasedEraOf (MinimumUTxOForShelleyBasedEra -> MinimumUTxO)
-> MinimumUTxOForShelleyBasedEra -> MinimumUTxO
forall a b. (a -> b) -> a -> b
$
    ShelleyBasedEra era
-> PParams (ShelleyLedgerEra era) -> MinimumUTxOForShelleyBasedEra
forall era.
ShelleyBasedEra era
-> PParams (ShelleyLedgerEra era) -> MinimumUTxOForShelleyBasedEra
MinimumUTxOForShelleyBasedEra ShelleyBasedEra era
era PParams (ShelleyLedgerEra era)
pp