module Cooked.MockChain.GenerateTx.Mint (toMintValue) where

import Cardano.Api qualified as Cardano
import Control.Monad
import Cooked.MockChain.BlockChain
import Cooked.MockChain.GenerateTx.Common
import Cooked.MockChain.GenerateTx.Witness
import Cooked.Skeleton
import Data.Map qualified as Map
import Ledger.Tx.CardanoAPI qualified as Ledger
import Plutus.Script.Utils.Scripts qualified as Script

-- | Converts the 'TxSkelMints' into a 'TxMintValue'
toMintValue :: (MonadBlockChainBalancing m) => TxSkelMints -> m (Cardano.TxMintValue Cardano.BuildTx Cardano.ConwayEra)
toMintValue :: forall (m :: * -> *).
MonadBlockChainBalancing m =>
TxSkelMints -> m (TxMintValue BuildTx ConwayEra)
toMintValue TxSkelMints
mints | TxSkelMints -> Bool
forall a. Map (Versioned MintingPolicy) a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null TxSkelMints
mints = TxMintValue BuildTx ConwayEra -> m (TxMintValue BuildTx ConwayEra)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return TxMintValue BuildTx ConwayEra
forall build era. TxMintValue build era
Cardano.TxMintNone
toMintValue TxSkelMints
mints | Value
mintValue <- TxSkelMints -> Value
txSkelMintsValue TxSkelMints
mints = do
  Value
mintVal <-
    String -> Either ToCardanoError Value -> m Value
forall (m :: * -> *) a.
MonadError MockChainError m =>
String -> Either ToCardanoError a -> m a
throwOnToCardanoError
      (String
"toMintValue: Unable to translate minted value " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Value -> String
forall a. Show a => a -> String
show Value
mintValue)
      (Value -> Either ToCardanoError Value
Ledger.toCardanoValue Value
mintValue)
  ([(PolicyId, ScriptWitness WitCtxMint ConwayEra)]
-> Map PolicyId (ScriptWitness WitCtxMint ConwayEra)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList -> Map PolicyId (ScriptWitness WitCtxMint ConwayEra)
witnessMap) <-
    [(Versioned MintingPolicy, TxSkelRedeemer, TokenName, Integer)]
-> ((Versioned MintingPolicy, TxSkelRedeemer, TokenName, Integer)
    -> m (PolicyId, ScriptWitness WitCtxMint ConwayEra))
-> m [(PolicyId, ScriptWitness WitCtxMint ConwayEra)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM (TxSkelMints
-> [(Versioned MintingPolicy, TxSkelRedeemer, TokenName, Integer)]
txSkelMintsToList TxSkelMints
mints) (((Versioned MintingPolicy, TxSkelRedeemer, TokenName, Integer)
  -> m (PolicyId, ScriptWitness WitCtxMint ConwayEra))
 -> m [(PolicyId, ScriptWitness WitCtxMint ConwayEra)])
-> ((Versioned MintingPolicy, TxSkelRedeemer, TokenName, Integer)
    -> m (PolicyId, ScriptWitness WitCtxMint ConwayEra))
-> m [(PolicyId, ScriptWitness WitCtxMint ConwayEra)]
forall a b. (a -> b) -> a -> b
$
      \(Versioned MintingPolicy
policy, TxSkelRedeemer
redeemer, TokenName
_, Integer
_) -> do
        PolicyId
policyId <-
          String -> Either ToCardanoError PolicyId -> m PolicyId
forall (m :: * -> *) a.
MonadError MockChainError m =>
String -> Either ToCardanoError a -> m a
throwOnToCardanoError
            String
"toMintValue: Unable to translate minting policy hash"
            (MintingPolicyHash -> Either ToCardanoError PolicyId
Ledger.toCardanoPolicyId (Versioned MintingPolicy -> MintingPolicyHash
Script.mintingPolicyHash Versioned MintingPolicy
policy))
        ScriptWitness WitCtxMint ConwayEra
mintWitness <- Versioned MintingPolicy
-> TxSkelRedeemer
-> ScriptDatum WitCtxMint
-> m (ScriptWitness WitCtxMint ConwayEra)
forall (m :: * -> *) a b.
(MonadBlockChainBalancing m, ToVersionedScript a) =>
a
-> TxSkelRedeemer -> ScriptDatum b -> m (ScriptWitness b ConwayEra)
toScriptWitness Versioned MintingPolicy
policy TxSkelRedeemer
redeemer ScriptDatum WitCtxMint
Cardano.NoScriptDatumForMint
        (PolicyId, ScriptWitness WitCtxMint ConwayEra)
-> m (PolicyId, ScriptWitness WitCtxMint ConwayEra)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (PolicyId
policyId, ScriptWitness WitCtxMint ConwayEra
mintWitness)
  TxMintValue BuildTx ConwayEra -> m (TxMintValue BuildTx ConwayEra)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (TxMintValue BuildTx ConwayEra
 -> m (TxMintValue BuildTx ConwayEra))
-> TxMintValue BuildTx ConwayEra
-> m (TxMintValue BuildTx ConwayEra)
forall a b. (a -> b) -> a -> b
$ MaryEraOnwards ConwayEra
-> Value
-> BuildTxWith
     BuildTx (Map PolicyId (ScriptWitness WitCtxMint ConwayEra))
-> TxMintValue BuildTx ConwayEra
forall era build.
MaryEraOnwards era
-> Value
-> BuildTxWith build (Map PolicyId (ScriptWitness WitCtxMint era))
-> TxMintValue build era
Cardano.TxMintValue MaryEraOnwards ConwayEra
Cardano.MaryEraOnwardsConway Value
mintVal (Map PolicyId (ScriptWitness WitCtxMint ConwayEra)
-> BuildTxWith
     BuildTx (Map PolicyId (ScriptWitness WitCtxMint ConwayEra))
forall a. a -> BuildTxWith BuildTx a
Cardano.BuildTxWith Map PolicyId (ScriptWitness WitCtxMint ConwayEra)
witnessMap)