{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}

module Cardano.CLI.EraBased.Script.Mint.Types
  ( CliScriptWitnessError (..)
  , CliMintScriptRequirements (..)
  , SimpleOrPlutusScriptCliArgs (..)
  , createSimpleOrPlutusScriptFromCliArgs
  , PlutusRefScriptCliArgs (..)
  , createPlutusReferenceScriptFromCliArgs
  , SimpleRefScriptCliArgs (..)
  , createSimpleReferenceScriptFromCliArgs
  , MintScriptWitnessWithPolicyId (..)
  )
where

import           Cardano.Api

import           Cardano.CLI.Types.Common (ScriptDataOrFile)
import           Cardano.CLI.Types.Errors.PlutusScriptDecodeError
import           Cardano.CLI.Types.Errors.ScriptDataError
import           Cardano.CLI.Types.Errors.ScriptDecodeError

-- We always need the policy id when constructing a transaction that mints.
-- In the case of reference scripts, the user currently must provide the policy id (script hash)
-- in order to correctly construct the transaction.
data MintScriptWitnessWithPolicyId era
  = MintScriptWitnessWithPolicyId
  { forall era. MintScriptWitnessWithPolicyId era -> PolicyId
mswPolId :: PolicyId
  , forall era.
MintScriptWitnessWithPolicyId era -> ScriptWitness WitCtxMint era
mswScriptWitness :: ScriptWitness WitCtxMint era
  }
  deriving Int -> MintScriptWitnessWithPolicyId era -> ShowS
[MintScriptWitnessWithPolicyId era] -> ShowS
MintScriptWitnessWithPolicyId era -> String
(Int -> MintScriptWitnessWithPolicyId era -> ShowS)
-> (MintScriptWitnessWithPolicyId era -> String)
-> ([MintScriptWitnessWithPolicyId era] -> ShowS)
-> Show (MintScriptWitnessWithPolicyId era)
forall era. Int -> MintScriptWitnessWithPolicyId era -> ShowS
forall era. [MintScriptWitnessWithPolicyId era] -> ShowS
forall era. MintScriptWitnessWithPolicyId era -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall era. Int -> MintScriptWitnessWithPolicyId era -> ShowS
showsPrec :: Int -> MintScriptWitnessWithPolicyId era -> ShowS
$cshow :: forall era. MintScriptWitnessWithPolicyId era -> String
show :: MintScriptWitnessWithPolicyId era -> String
$cshowList :: forall era. [MintScriptWitnessWithPolicyId era] -> ShowS
showList :: [MintScriptWitnessWithPolicyId era] -> ShowS
Show

data CliMintScriptRequirements
  = OnDiskSimpleOrPlutusScript SimpleOrPlutusScriptCliArgs
  | OnDiskSimpleRefScript SimpleRefScriptCliArgs
  | OnDiskPlutusRefScript PlutusRefScriptCliArgs
  deriving Int -> CliMintScriptRequirements -> ShowS
[CliMintScriptRequirements] -> ShowS
CliMintScriptRequirements -> String
(Int -> CliMintScriptRequirements -> ShowS)
-> (CliMintScriptRequirements -> String)
-> ([CliMintScriptRequirements] -> ShowS)
-> Show CliMintScriptRequirements
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CliMintScriptRequirements -> ShowS
showsPrec :: Int -> CliMintScriptRequirements -> ShowS
$cshow :: CliMintScriptRequirements -> String
show :: CliMintScriptRequirements -> String
$cshowList :: [CliMintScriptRequirements] -> ShowS
showList :: [CliMintScriptRequirements] -> ShowS
Show

data SimpleOrPlutusScriptCliArgs
  = OnDiskSimpleScriptCliArgs
      (File ScriptInAnyLang In)
  | OnDiskPlutusScriptCliArgs
      (File ScriptInAnyLang In)
      ScriptDataOrFile
      ExecutionUnits
  deriving Int -> SimpleOrPlutusScriptCliArgs -> ShowS
[SimpleOrPlutusScriptCliArgs] -> ShowS
SimpleOrPlutusScriptCliArgs -> String
(Int -> SimpleOrPlutusScriptCliArgs -> ShowS)
-> (SimpleOrPlutusScriptCliArgs -> String)
-> ([SimpleOrPlutusScriptCliArgs] -> ShowS)
-> Show SimpleOrPlutusScriptCliArgs
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SimpleOrPlutusScriptCliArgs -> ShowS
showsPrec :: Int -> SimpleOrPlutusScriptCliArgs -> ShowS
$cshow :: SimpleOrPlutusScriptCliArgs -> String
show :: SimpleOrPlutusScriptCliArgs -> String
$cshowList :: [SimpleOrPlutusScriptCliArgs] -> ShowS
showList :: [SimpleOrPlutusScriptCliArgs] -> ShowS
Show

createSimpleOrPlutusScriptFromCliArgs
  :: File ScriptInAnyLang In
  -> Maybe (ScriptDataOrFile, ExecutionUnits)
  -> CliMintScriptRequirements
createSimpleOrPlutusScriptFromCliArgs :: File ScriptInAnyLang 'In
-> Maybe (ScriptDataOrFile, ExecutionUnits)
-> CliMintScriptRequirements
createSimpleOrPlutusScriptFromCliArgs File ScriptInAnyLang 'In
scriptFp Maybe (ScriptDataOrFile, ExecutionUnits)
Nothing =
  SimpleOrPlutusScriptCliArgs -> CliMintScriptRequirements
OnDiskSimpleOrPlutusScript (SimpleOrPlutusScriptCliArgs -> CliMintScriptRequirements)
-> SimpleOrPlutusScriptCliArgs -> CliMintScriptRequirements
forall a b. (a -> b) -> a -> b
$ File ScriptInAnyLang 'In -> SimpleOrPlutusScriptCliArgs
OnDiskSimpleScriptCliArgs File ScriptInAnyLang 'In
scriptFp
createSimpleOrPlutusScriptFromCliArgs File ScriptInAnyLang 'In
scriptFp (Just (ScriptDataOrFile
redeemerFile, ExecutionUnits
execUnits)) =
  SimpleOrPlutusScriptCliArgs -> CliMintScriptRequirements
OnDiskSimpleOrPlutusScript (SimpleOrPlutusScriptCliArgs -> CliMintScriptRequirements)
-> SimpleOrPlutusScriptCliArgs -> CliMintScriptRequirements
forall a b. (a -> b) -> a -> b
$ File ScriptInAnyLang 'In
-> ScriptDataOrFile
-> ExecutionUnits
-> SimpleOrPlutusScriptCliArgs
OnDiskPlutusScriptCliArgs File ScriptInAnyLang 'In
scriptFp ScriptDataOrFile
redeemerFile ExecutionUnits
execUnits

data SimpleRefScriptCliArgs
  = SimpleRefScriptCliArgs
      TxIn
      PolicyId
  deriving Int -> SimpleRefScriptCliArgs -> ShowS
[SimpleRefScriptCliArgs] -> ShowS
SimpleRefScriptCliArgs -> String
(Int -> SimpleRefScriptCliArgs -> ShowS)
-> (SimpleRefScriptCliArgs -> String)
-> ([SimpleRefScriptCliArgs] -> ShowS)
-> Show SimpleRefScriptCliArgs
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SimpleRefScriptCliArgs -> ShowS
showsPrec :: Int -> SimpleRefScriptCliArgs -> ShowS
$cshow :: SimpleRefScriptCliArgs -> String
show :: SimpleRefScriptCliArgs -> String
$cshowList :: [SimpleRefScriptCliArgs] -> ShowS
showList :: [SimpleRefScriptCliArgs] -> ShowS
Show

createSimpleReferenceScriptFromCliArgs
  :: TxIn
  -> PolicyId
  -> CliMintScriptRequirements
createSimpleReferenceScriptFromCliArgs :: TxIn -> PolicyId -> CliMintScriptRequirements
createSimpleReferenceScriptFromCliArgs TxIn
txin PolicyId
polid =
  SimpleRefScriptCliArgs -> CliMintScriptRequirements
OnDiskSimpleRefScript (SimpleRefScriptCliArgs -> CliMintScriptRequirements)
-> SimpleRefScriptCliArgs -> CliMintScriptRequirements
forall a b. (a -> b) -> a -> b
$ TxIn -> PolicyId -> SimpleRefScriptCliArgs
SimpleRefScriptCliArgs TxIn
txin PolicyId
polid

data PlutusRefScriptCliArgs
  = PlutusRefScriptCliArgs
      TxIn
      AnyPlutusScriptVersion
      ScriptDataOrFile
      ExecutionUnits
      PolicyId
  deriving Int -> PlutusRefScriptCliArgs -> ShowS
[PlutusRefScriptCliArgs] -> ShowS
PlutusRefScriptCliArgs -> String
(Int -> PlutusRefScriptCliArgs -> ShowS)
-> (PlutusRefScriptCliArgs -> String)
-> ([PlutusRefScriptCliArgs] -> ShowS)
-> Show PlutusRefScriptCliArgs
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PlutusRefScriptCliArgs -> ShowS
showsPrec :: Int -> PlutusRefScriptCliArgs -> ShowS
$cshow :: PlutusRefScriptCliArgs -> String
show :: PlutusRefScriptCliArgs -> String
$cshowList :: [PlutusRefScriptCliArgs] -> ShowS
showList :: [PlutusRefScriptCliArgs] -> ShowS
Show

createPlutusReferenceScriptFromCliArgs
  :: TxIn
  -> AnyPlutusScriptVersion
  -> ScriptDataOrFile
  -> ExecutionUnits
  -> PolicyId
  -> CliMintScriptRequirements
createPlutusReferenceScriptFromCliArgs :: TxIn
-> AnyPlutusScriptVersion
-> ScriptDataOrFile
-> ExecutionUnits
-> PolicyId
-> CliMintScriptRequirements
createPlutusReferenceScriptFromCliArgs TxIn
txin AnyPlutusScriptVersion
scriptVersion ScriptDataOrFile
scriptData ExecutionUnits
execUnits PolicyId
polid =
  PlutusRefScriptCliArgs -> CliMintScriptRequirements
OnDiskPlutusRefScript (PlutusRefScriptCliArgs -> CliMintScriptRequirements)
-> PlutusRefScriptCliArgs -> CliMintScriptRequirements
forall a b. (a -> b) -> a -> b
$ TxIn
-> AnyPlutusScriptVersion
-> ScriptDataOrFile
-> ExecutionUnits
-> PolicyId
-> PlutusRefScriptCliArgs
PlutusRefScriptCliArgs TxIn
txin AnyPlutusScriptVersion
scriptVersion ScriptDataOrFile
scriptData ExecutionUnits
execUnits PolicyId
polid

data CliScriptWitnessError
  = SimpleScriptWitnessDecodeError ScriptDecodeError
  | PlutusScriptWitnessDecodeError PlutusScriptDecodeError
  | PlutusScriptWitnessLanguageNotSupportedInEra
      AnyPlutusScriptVersion
      AnyShelleyBasedEra
  | PlutusScriptWitnessRedeemerError ScriptDataError

instance Error CliScriptWitnessError where
  prettyError :: forall ann. CliScriptWitnessError -> Doc ann
prettyError = \case
    SimpleScriptWitnessDecodeError ScriptDecodeError
err -> ScriptDecodeError -> Doc ann
forall e ann. Error e => e -> Doc ann
forall ann. ScriptDecodeError -> Doc ann
prettyError ScriptDecodeError
err
    PlutusScriptWitnessDecodeError PlutusScriptDecodeError
err -> PlutusScriptDecodeError -> Doc ann
forall e ann. Error e => e -> Doc ann
forall ann. PlutusScriptDecodeError -> Doc ann
prettyError PlutusScriptDecodeError
err
    PlutusScriptWitnessLanguageNotSupportedInEra AnyPlutusScriptVersion
version AnyShelleyBasedEra
era ->
      Doc ann
"Plutus script version " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> AnyPlutusScriptVersion -> Doc ann
forall a ann. Show a => a -> Doc ann
pshow AnyPlutusScriptVersion
version Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
" is not supported in era " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> AnyShelleyBasedEra -> Doc ann
forall a ann. Show a => a -> Doc ann
pshow AnyShelleyBasedEra
era
    PlutusScriptWitnessRedeemerError ScriptDataError
err -> ScriptDataError -> Doc ann
forall ann. ScriptDataError -> Doc ann
renderScriptDataError ScriptDataError
err