{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

module Cardano.CLI.EraIndependent.Debug.TransactionView.Run
  ( runTransactionViewCmd
  )
where

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

import Cardano.CLI.Compatible.Exception
  ( CIO
  , fromEitherCli
  , fromEitherIOCli
  )
import Cardano.CLI.Compatible.Json.Friendly
  ( friendlyTx
  , friendlyTxBody
  )
import Cardano.CLI.EraIndependent.Debug.TransactionView.Command
import Cardano.CLI.Read
import Cardano.CLI.Type.Common

runTransactionViewCmd
  :: ()
  => TransactionViewCmdArgs
  -> CIO e ()
runTransactionViewCmd :: forall e. TransactionViewCmdArgs -> CIO e ()
runTransactionViewCmd
  TransactionViewCmdArgs
    { Vary '[FormatJson, FormatYaml]
outputFormat :: Vary '[FormatJson, FormatYaml]
outputFormat :: TransactionViewCmdArgs -> Vary '[FormatJson, FormatYaml]
outputFormat
    , Maybe (File () 'Out)
mOutFile :: Maybe (File () 'Out)
mOutFile :: TransactionViewCmdArgs -> Maybe (File () 'Out)
mOutFile
    , InputTxBodyOrTxFile
inputTxBodyOrTxFile :: InputTxBodyOrTxFile
inputTxBodyOrTxFile :: TransactionViewCmdArgs -> InputTxBodyOrTxFile
inputTxBodyOrTxFile
    } =
    case InputTxBodyOrTxFile
inputTxBodyOrTxFile of
      InputTxBodyFile (File FilePath
txbodyFilePath) -> do
        txbodyFile <- IO FileOrPipe -> RIO e FileOrPipe
forall a. IO a -> RIO e a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO FileOrPipe -> RIO e FileOrPipe)
-> IO FileOrPipe -> RIO e FileOrPipe
forall a b. (a -> b) -> a -> b
$ FilePath -> IO FileOrPipe
fileOrPipe FilePath
txbodyFilePath
        unwitnessed <-
          fromEitherIOCli $
            readFileTxBody txbodyFile
        InAnyShelleyBasedEra (sbe :: ShelleyBasedEra era) txbody <-
          pure $ unIncompleteTxBody unwitnessed
        era <- fromEitherCli (Exp.sbeToEra sbe)
        -- Why are we differentiating between a transaction body and a transaction?
        -- In the case of a transaction body, we /could/ simply call @makeSignedTransaction []@
        -- to get a transaction which would allow us to reuse friendlyTxBS. However,
        -- this would mean that we'd have an empty list of witnesses mentioned in the output, which
        -- is arguably not part of the transaction body.
        let ShelleyTx _ ledgerTx = makeSignedTransaction [] txbody
            unsignedTx :: Exp.UnsignedTx (Exp.LedgerEra era)
            unsignedTx = Era era
-> (EraCommonConstraints era => UnsignedTx (LedgerEra era))
-> UnsignedTx (LedgerEra era)
forall era a. Era era -> (EraCommonConstraints era => a) -> a
Exp.obtainCommonConstraints Era era
era ((EraCommonConstraints era => UnsignedTx (LedgerEra era))
 -> UnsignedTx (LedgerEra era))
-> (EraCommonConstraints era => UnsignedTx (LedgerEra era))
-> UnsignedTx (LedgerEra era)
forall a b. (a -> b) -> a -> b
$ Tx TopTx (LedgerEra era) -> UnsignedTx (LedgerEra era)
forall era. EraTx era => Tx TopTx era -> UnsignedTx era
Exp.UnsignedTx Tx TopTx (ShelleyLedgerEra era)
Tx TopTx (LedgerEra era)
ledgerTx
        fromEitherIOCli @(FileError ()) $
          friendlyTxBody outputFormat mOutFile era unsignedTx
      InputTxFile (File FilePath
txFilePath) -> do
        txFile <- IO FileOrPipe -> RIO e FileOrPipe
forall a. IO a -> RIO e a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO FileOrPipe -> RIO e FileOrPipe)
-> IO FileOrPipe -> RIO e FileOrPipe
forall a b. (a -> b) -> a -> b
$ FilePath -> IO FileOrPipe
fileOrPipe FilePath
txFilePath
        InAnyShelleyBasedEra (sbe :: ShelleyBasedEra era) tx <- fromEitherIOCli (readFileTx txFile)
        era <- fromEitherCli (Exp.sbeToEra sbe)
        let ShelleyTx _ ledgerTx = tx
            signedTx :: Exp.SignedTx era
            signedTx = Era era
-> (EraCommonConstraints era => SignedTx era) -> SignedTx era
forall era a. Era era -> (EraCommonConstraints era => a) -> a
Exp.obtainCommonConstraints Era era
era ((EraCommonConstraints era => SignedTx era) -> SignedTx era)
-> (EraCommonConstraints era => SignedTx era) -> SignedTx era
forall a b. (a -> b) -> a -> b
$ Tx TopTx (ShelleyLedgerEra era) -> SignedTx era
forall era.
EraTx (ShelleyLedgerEra era) =>
Tx TopTx (ShelleyLedgerEra era) -> SignedTx era
Exp.SignedTx Tx TopTx (ShelleyLedgerEra era)
ledgerTx
        fromEitherIOCli @(FileError ()) $
          friendlyTx outputFormat mOutFile era signedTx