{-# LANGUAGE GADTs #-}

module Cardano.CLI.EraBased.Script.Guard.Option (pTxGuardArguments) where

import Cardano.Api
import Cardano.Api.Experimental qualified as Exp

import Cardano.CLI.EraBased.Common.Option
import Cardano.CLI.EraBased.Script.Guard.Type
import Cardano.CLI.Type.Common

import Control.Applicative ((<|>))
import Options.Applicative (Parser, many, optional)

pTxGuardArguments :: Exp.Era era -> BalanceTxExecUnits -> Parser (TxGuardArguments era)
pTxGuardArguments :: forall era.
Era era -> BalanceTxExecUnits -> Parser (TxGuardArguments era)
pTxGuardArguments Era era
Exp.ConwayEra BalanceTxExecUnits
_ = [RequiredSigner] -> TxGuardArguments era
[RequiredSigner] -> TxGuardArguments ConwayEra
ConwayRequiredSignerArguments ([RequiredSigner] -> TxGuardArguments era)
-> Parser [RequiredSigner] -> Parser (TxGuardArguments era)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser RequiredSigner -> Parser [RequiredSigner]
forall a. Parser a -> Parser [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many Parser RequiredSigner
pRequiredSigner
pTxGuardArguments Era era
Exp.DijkstraEra BalanceTxExecUnits
balance =
  [Guard] -> TxGuardArguments era
[Guard] -> TxGuardArguments DijkstraEra
DijkstraGuardArguments ([Guard] -> TxGuardArguments era)
-> Parser [Guard] -> Parser (TxGuardArguments era)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Guard -> Parser [Guard]
forall a. Parser a -> Parser [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many ((RequiredSigner -> Guard
KeyGuard (RequiredSigner -> Guard) -> Parser RequiredSigner -> Parser Guard
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser RequiredSigner
pRequiredSigner) Parser Guard -> Parser Guard -> Parser Guard
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> BalanceTxExecUnits -> Parser Guard
pScriptGuard BalanceTxExecUnits
balance)

pScriptGuard :: BalanceTxExecUnits -> Parser Guard
pScriptGuard :: BalanceTxExecUnits -> Parser Guard
pScriptGuard BalanceTxExecUnits
balance =
  ( GuardScriptSource
-> Maybe (ScriptDataOrFile, ExecutionUnits) -> Guard
ScriptGuard (GuardScriptSource
 -> Maybe (ScriptDataOrFile, ExecutionUnits) -> Guard)
-> (File ScriptInAnyLang 'In -> GuardScriptSource)
-> File ScriptInAnyLang 'In
-> Maybe (ScriptDataOrFile, ExecutionUnits)
-> Guard
forall b c a. (b -> c) -> (a -> b) -> a -> c
. File ScriptInAnyLang 'In -> GuardScriptSource
GuardScriptOnDisk
      (File ScriptInAnyLang 'In
 -> Maybe (ScriptDataOrFile, ExecutionUnits) -> Guard)
-> Parser (File ScriptInAnyLang 'In)
-> Parser (Maybe (ScriptDataOrFile, ExecutionUnits) -> Guard)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String
-> Maybe String -> String -> Parser (File ScriptInAnyLang 'In)
pScriptFor
        String
"guard-script-file"
        Maybe String
forall a. Maybe a
Nothing
        String
"Native or Plutus V4 script whose approval this transaction requires. Plutus guards require a redeemer; native guards accept neither redeemers nor execution units."
      Parser (Maybe (ScriptDataOrFile, ExecutionUnits) -> Guard)
-> Parser (Maybe (ScriptDataOrFile, ExecutionUnits))
-> Parser Guard
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (ScriptDataOrFile, ExecutionUnits)
-> Parser (Maybe (ScriptDataOrFile, ExecutionUnits))
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser (ScriptDataOrFile, ExecutionUnits)
pRedeemer
  )
    Parser Guard -> Parser Guard -> Parser Guard
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ( GuardScriptSource
-> Maybe (ScriptDataOrFile, ExecutionUnits) -> Guard
ScriptGuard
            (GuardScriptSource
 -> Maybe (ScriptDataOrFile, ExecutionUnits) -> Guard)
-> Parser GuardScriptSource
-> Parser (Maybe (ScriptDataOrFile, ExecutionUnits) -> Guard)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ( TxIn -> ScriptHash -> GuardScriptSource
NativeGuardScriptReference
                    (TxIn -> ScriptHash -> GuardScriptSource)
-> Parser TxIn -> Parser (ScriptHash -> GuardScriptSource)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> String -> Parser TxIn
pReferenceTxIn String
"simple-guard-script-" String
"native"
                    Parser (ScriptHash -> GuardScriptSource)
-> Parser ScriptHash -> Parser GuardScriptSource
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ScriptHash
pGuardScriptHash
                )
            Parser (Maybe (ScriptDataOrFile, ExecutionUnits) -> Guard)
-> Parser (Maybe (ScriptDataOrFile, ExecutionUnits))
-> Parser Guard
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe (ScriptDataOrFile, ExecutionUnits)
-> Parser (Maybe (ScriptDataOrFile, ExecutionUnits))
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (ScriptDataOrFile, ExecutionUnits)
forall a. Maybe a
Nothing
        )
    Parser Guard -> Parser Guard -> Parser Guard
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ( GuardScriptSource
-> Maybe (ScriptDataOrFile, ExecutionUnits) -> Guard
ScriptGuard
            (GuardScriptSource
 -> Maybe (ScriptDataOrFile, ExecutionUnits) -> Guard)
-> Parser GuardScriptSource
-> Parser (Maybe (ScriptDataOrFile, ExecutionUnits) -> Guard)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ( TxIn -> ScriptHash -> GuardScriptSource
PlutusGuardScriptReference
                    (TxIn -> ScriptHash -> GuardScriptSource)
-> Parser TxIn -> Parser (ScriptHash -> GuardScriptSource)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> String -> Parser TxIn
pReferenceTxIn String
"guard-" String
"Plutus V4"
                    Parser (ScriptHash -> GuardScriptSource)
-> Parser AnySLanguage -> Parser (ScriptHash -> GuardScriptSource)
forall a b. Parser a -> Parser b -> Parser a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Era DijkstraEra -> String -> Parser AnySLanguage
forall era. Era era -> String -> Parser AnySLanguage
pPlutusV4ReferenceLanguage Era DijkstraEra
Exp.DijkstraEra String
"guard-"
                    Parser (ScriptHash -> GuardScriptSource)
-> Parser ScriptHash -> Parser GuardScriptSource
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ScriptHash
pGuardScriptHash
                )
            Parser (Maybe (ScriptDataOrFile, ExecutionUnits) -> Guard)
-> Parser (Maybe (ScriptDataOrFile, ExecutionUnits))
-> Parser Guard
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ((ScriptDataOrFile, ExecutionUnits)
-> Maybe (ScriptDataOrFile, ExecutionUnits)
forall a. a -> Maybe a
Just ((ScriptDataOrFile, ExecutionUnits)
 -> Maybe (ScriptDataOrFile, ExecutionUnits))
-> Parser (ScriptDataOrFile, ExecutionUnits)
-> Parser (Maybe (ScriptDataOrFile, ExecutionUnits))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser (ScriptDataOrFile, ExecutionUnits)
pRedeemer)
        )
 where
  pGuardScriptHash :: Parser ScriptHash
pGuardScriptHash =
    String -> String -> Parser ScriptHash
pScriptHash
      String
"guard-script-hash"
      String
"Hash of the guard script at the preceding reference input."
  pRedeemer :: Parser (ScriptDataOrFile, ExecutionUnits)
pRedeemer =
    (,)
      (ScriptDataOrFile
 -> ExecutionUnits -> (ScriptDataOrFile, ExecutionUnits))
-> Parser ScriptDataOrFile
-> Parser (ExecutionUnits -> (ScriptDataOrFile, ExecutionUnits))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> String -> String -> Parser ScriptDataOrFile
pScriptDataOrFile
        String
"guard-redeemer"
        String
"Redeemer for the preceding Plutus V4 guard."
        String
"Redeemer file for the preceding Plutus V4 guard."
      Parser (ExecutionUnits -> (ScriptDataOrFile, ExecutionUnits))
-> Parser ExecutionUnits
-> Parser (ScriptDataOrFile, ExecutionUnits)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> case BalanceTxExecUnits
balance of
        BalanceTxExecUnits
AutoBalance -> ExecutionUnits -> Parser ExecutionUnits
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Natural -> Natural -> ExecutionUnits
ExecutionUnits Natural
0 Natural
0)
        BalanceTxExecUnits
ManualBalance -> String -> Parser ExecutionUnits
pExecutionUnits String
"guard"