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

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

type MintGen a = TxGen (Map Api.TxOutRef Api.TxOut) a

-- | Converts the 'TxSkelMints' into a 'TxMintValue'
toMintValue :: TxSkelMints -> MintGen (Cardano.TxMintValue Cardano.BuildTx Cardano.ConwayEra)
toMintValue :: TxSkelMints -> MintGen (TxMintValue BuildTx ConwayEra)
toMintValue TxSkelMints
mints =
  if TxSkelMints -> Bool
forall a. Map (Versioned MintingPolicy) a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null TxSkelMints
mints
    then TxMintValue BuildTx ConwayEra
-> MintGen (TxMintValue BuildTx ConwayEra)
forall a.
a -> ReaderT (Map TxOutRef TxOut) (Either GenerateTxError) a
forall (m :: * -> *) a. Monad m => a -> m a
return TxMintValue BuildTx ConwayEra
forall build era. TxMintValue build era
Cardano.TxMintNone
    else do
      let mintValue :: Value
mintValue = TxSkelMints -> Value
txSkelMintsValue TxSkelMints
mints
      Value
mintVal <-
        String
-> Either ToCardanoError Value -> TxGen (Map TxOutRef TxOut) Value
forall a context.
String -> Either ToCardanoError a -> TxGen context 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)
    -> ReaderT
         (Map TxOutRef TxOut)
         (Either GenerateTxError)
         (PolicyId, ScriptWitness WitCtxMint ConwayEra))
-> ReaderT
     (Map TxOutRef TxOut)
     (Either GenerateTxError)
     [(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)
  -> ReaderT
       (Map TxOutRef TxOut)
       (Either GenerateTxError)
       (PolicyId, ScriptWitness WitCtxMint ConwayEra))
 -> ReaderT
      (Map TxOutRef TxOut)
      (Either GenerateTxError)
      [(PolicyId, ScriptWitness WitCtxMint ConwayEra)])
-> ((Versioned MintingPolicy, TxSkelRedeemer, TokenName, Integer)
    -> ReaderT
         (Map TxOutRef TxOut)
         (Either GenerateTxError)
         (PolicyId, ScriptWitness WitCtxMint ConwayEra))
-> ReaderT
     (Map TxOutRef TxOut)
     (Either GenerateTxError)
     [(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
-> TxGen (Map TxOutRef TxOut) PolicyId
forall a context.
String -> Either ToCardanoError a -> TxGen context 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
-> WitnessGen (ScriptWitness WitCtxMint ConwayEra)
forall a b.
ToVersionedScript a =>
a
-> TxSkelRedeemer
-> ScriptDatum b
-> WitnessGen (ScriptWitness b ConwayEra)
toScriptWitness Versioned MintingPolicy
policy TxSkelRedeemer
redeemer ScriptDatum WitCtxMint
Cardano.NoScriptDatumForMint
            (PolicyId, ScriptWitness WitCtxMint ConwayEra)
-> ReaderT
     (Map TxOutRef TxOut)
     (Either GenerateTxError)
     (PolicyId, ScriptWitness WitCtxMint ConwayEra)
forall a.
a -> ReaderT (Map TxOutRef TxOut) (Either GenerateTxError) a
forall (m :: * -> *) a. Monad m => a -> m a
return (PolicyId
policyId, ScriptWitness WitCtxMint ConwayEra
mintWitness)
      TxMintValue BuildTx ConwayEra
-> MintGen (TxMintValue BuildTx ConwayEra)
forall a.
a -> ReaderT (Map TxOutRef TxOut) (Either GenerateTxError) a
forall (m :: * -> *) a. Monad m => a -> m a
return (TxMintValue BuildTx ConwayEra
 -> MintGen (TxMintValue BuildTx ConwayEra))
-> TxMintValue BuildTx ConwayEra
-> MintGen (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)