{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Cardano.CLI.EraBased.Run.Governance.Poll
  ( runGovernancePollCmds
  , runGovernanceCreatePollCmd
  , runGovernanceAnswerPollCmd
  , runGovernanceVerifyPollCmd
  )
where

import           Cardano.Api
import           Cardano.Api.Shelley

import qualified Cardano.CLI.EraBased.Commands.Governance.Poll as Cmd
import           Cardano.CLI.Read
import           Cardano.CLI.Types.Errors.GovernanceCmdError

import           Control.Monad
import qualified Data.ByteString.Char8 as BSC
import           Data.Function ((&))
import           Data.String (fromString)
import qualified Data.Text as Text
import qualified Data.Text.Encoding as Text
import qualified Data.Text.IO as Text
import qualified Data.Text.Read as Text
import qualified System.IO as IO
import           System.IO (stderr, stdin, stdout)

runGovernancePollCmds
  :: ()
  => Cmd.GovernancePollCmds era
  -> ExceptT GovernanceCmdError IO ()
runGovernancePollCmds :: forall era.
GovernancePollCmds era -> ExceptT GovernanceCmdError IO ()
runGovernancePollCmds = \case
  Cmd.GovernanceCreatePoll GovernanceCreatePollCmdArgs era
args -> GovernanceCreatePollCmdArgs era -> ExceptT GovernanceCmdError IO ()
forall era.
GovernanceCreatePollCmdArgs era -> ExceptT GovernanceCmdError IO ()
runGovernanceCreatePollCmd GovernanceCreatePollCmdArgs era
args
  Cmd.GovernanceAnswerPoll GovernanceAnswerPollCmdArgs era
args -> GovernanceAnswerPollCmdArgs era -> ExceptT GovernanceCmdError IO ()
forall era.
GovernanceAnswerPollCmdArgs era -> ExceptT GovernanceCmdError IO ()
runGovernanceAnswerPollCmd GovernanceAnswerPollCmdArgs era
args
  Cmd.GovernanceVerifyPoll GovernanceVerifyPollCmdArgs era
args -> GovernanceVerifyPollCmdArgs era -> ExceptT GovernanceCmdError IO ()
forall era.
GovernanceVerifyPollCmdArgs era -> ExceptT GovernanceCmdError IO ()
runGovernanceVerifyPollCmd GovernanceVerifyPollCmdArgs era
args

runGovernanceCreatePollCmd
  :: ()
  => Cmd.GovernanceCreatePollCmdArgs era
  -> ExceptT GovernanceCmdError IO ()
runGovernanceCreatePollCmd :: forall era.
GovernanceCreatePollCmdArgs era -> ExceptT GovernanceCmdError IO ()
runGovernanceCreatePollCmd
  Cmd.GovernanceCreatePollCmdArgs
    { eon :: forall era.
GovernanceCreatePollCmdArgs era -> BabbageEraOnwards era
eon = BabbageEraOnwards era
_eon
    , prompt :: forall era. GovernanceCreatePollCmdArgs era -> Text
prompt = Text
govPollQuestion
    , choices :: forall era. GovernanceCreatePollCmdArgs era -> [Text]
choices = [Text]
govPollAnswers
    , nonce :: forall era. GovernanceCreatePollCmdArgs era -> Maybe Word
nonce = Maybe Word
govPollNonce
    , outFile :: forall era.
GovernanceCreatePollCmdArgs era -> File GovernancePoll 'Out
outFile = File GovernancePoll 'Out
out
    } = do
    let poll :: GovernancePoll
poll = GovernancePoll{Text
govPollQuestion :: Text
govPollQuestion :: Text
govPollQuestion, [Text]
govPollAnswers :: [Text]
govPollAnswers :: [Text]
govPollAnswers, Maybe Word
govPollNonce :: Maybe Word
govPollNonce :: Maybe Word
govPollNonce}

    let description :: TextEnvelopeDescr
description = String -> TextEnvelopeDescr
forall a. IsString a => String -> a
fromString (String -> TextEnvelopeDescr) -> String -> TextEnvelopeDescr
forall a b. (a -> b) -> a -> b
$ String
"An on-chain poll for SPOs: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
Text.unpack Text
govPollQuestion
    (FileError () -> GovernanceCmdError)
-> ExceptT (FileError ()) IO () -> ExceptT GovernanceCmdError IO ()
forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT FileError () -> GovernanceCmdError
GovernanceCmdTextEnvWriteError (ExceptT (FileError ()) IO () -> ExceptT GovernanceCmdError IO ())
-> (IO (Either (FileError ()) ()) -> ExceptT (FileError ()) IO ())
-> IO (Either (FileError ()) ())
-> ExceptT GovernanceCmdError IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO (Either (FileError ()) ()) -> ExceptT (FileError ()) IO ()
forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
newExceptT (IO (Either (FileError ()) ()) -> ExceptT GovernanceCmdError IO ())
-> IO (Either (FileError ()) ())
-> ExceptT GovernanceCmdError IO ()
forall a b. (a -> b) -> a -> b
$
      File GovernancePoll 'Out
-> Maybe TextEnvelopeDescr
-> GovernancePoll
-> IO (Either (FileError ()) ())
forall a content.
HasTextEnvelope a =>
File content 'Out
-> Maybe TextEnvelopeDescr -> a -> IO (Either (FileError ()) ())
writeFileTextEnvelope File GovernancePoll 'Out
out (TextEnvelopeDescr -> Maybe TextEnvelopeDescr
forall a. a -> Maybe a
Just TextEnvelopeDescr
description) GovernancePoll
poll

    let metadata :: Value
metadata =
          GovernancePoll -> TxMetadata
forall a. AsTxMetadata a => a -> TxMetadata
asTxMetadata GovernancePoll
poll
            TxMetadata -> (TxMetadata -> Value) -> Value
forall a b. a -> (a -> b) -> b
& TxMetadataJsonSchema -> TxMetadata -> Value
metadataToJson TxMetadataJsonSchema
TxMetadataJsonDetailedSchema

    let outPath :: ByteString
outPath = File GovernancePoll 'Out -> String
forall content (direction :: FileDirection).
File content direction -> String
unFile File GovernancePoll 'Out
out String -> (String -> ByteString) -> ByteString
forall a b. a -> (a -> b) -> b
& Text -> ByteString
Text.encodeUtf8 (Text -> ByteString) -> (String -> Text) -> String -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
Text.pack

    IO () -> ExceptT GovernanceCmdError IO ()
forall a. IO a -> ExceptT GovernanceCmdError IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ExceptT GovernanceCmdError IO ())
-> IO () -> ExceptT GovernanceCmdError IO ()
forall a b. (a -> b) -> a -> b
$ do
      Handle -> ByteString -> IO ()
BSC.hPutStrLn Handle
stderr (ByteString -> IO ()) -> ByteString -> IO ()
forall a b. (a -> b) -> a -> b
$
        [ByteString] -> ByteString
forall a. Monoid a => [a] -> a
mconcat
          [ ByteString
"Poll created successfully.\n"
          , ByteString
"Please submit a transaction using the resulting metadata.\n"
          ]
      Handle -> ByteString -> IO ()
BSC.hPutStrLn Handle
stdout (Value -> ByteString
forall a. ToJSON a => a -> ByteString
prettyPrintJSON Value
metadata)
      Handle -> ByteString -> IO ()
BSC.hPutStrLn Handle
stderr (ByteString -> IO ()) -> ByteString -> IO ()
forall a b. (a -> b) -> a -> b
$
        [ByteString] -> ByteString
forall a. Monoid a => [a] -> a
mconcat
          [ ByteString
"\n"
          , ByteString
"Hint (1): Use '--json-metadata-detailed-schema' and '--metadata-json-file' "
          , ByteString
"from the build or build-raw commands.\n"
          , ByteString
"Hint (2): You can redirect the standard output of this command to a JSON "
          , ByteString
"file to capture metadata.\n\n"
          , ByteString
"Note: A serialized version of the poll suitable for sharing with "
          , ByteString
"participants has been generated at '" ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
outPath ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
"'."
          ]

runGovernanceAnswerPollCmd
  :: ()
  => Cmd.GovernanceAnswerPollCmdArgs era
  -> ExceptT GovernanceCmdError IO ()
runGovernanceAnswerPollCmd :: forall era.
GovernanceAnswerPollCmdArgs era -> ExceptT GovernanceCmdError IO ()
runGovernanceAnswerPollCmd
  Cmd.GovernanceAnswerPollCmdArgs
    { eon :: forall era.
GovernanceAnswerPollCmdArgs era -> BabbageEraOnwards era
eon = BabbageEraOnwards era
_eon
    , pollFile :: forall era.
GovernanceAnswerPollCmdArgs era -> File GovernancePoll 'In
pollFile = File GovernancePoll 'In
pollFile
    , answerIndex :: forall era. GovernanceAnswerPollCmdArgs era -> Maybe Word
answerIndex = Maybe Word
maybeChoice
    , mOutFile :: forall era. GovernanceAnswerPollCmdArgs era -> Maybe (File () 'Out)
mOutFile = Maybe (File () 'Out)
mOutFile
    } = do
    GovernancePoll
poll <-
      (FileError TextEnvelopeError -> GovernanceCmdError)
-> ExceptT (FileError TextEnvelopeError) IO GovernancePoll
-> ExceptT GovernanceCmdError IO GovernancePoll
forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT FileError TextEnvelopeError -> GovernanceCmdError
GovernanceCmdTextEnvReadError (ExceptT (FileError TextEnvelopeError) IO GovernancePoll
 -> ExceptT GovernanceCmdError IO GovernancePoll)
-> (IO (Either (FileError TextEnvelopeError) GovernancePoll)
    -> ExceptT (FileError TextEnvelopeError) IO GovernancePoll)
-> IO (Either (FileError TextEnvelopeError) GovernancePoll)
-> ExceptT GovernanceCmdError IO GovernancePoll
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO (Either (FileError TextEnvelopeError) GovernancePoll)
-> ExceptT (FileError TextEnvelopeError) IO GovernancePoll
forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
newExceptT (IO (Either (FileError TextEnvelopeError) GovernancePoll)
 -> ExceptT GovernanceCmdError IO GovernancePoll)
-> IO (Either (FileError TextEnvelopeError) GovernancePoll)
-> ExceptT GovernanceCmdError IO GovernancePoll
forall a b. (a -> b) -> a -> b
$
        AsType GovernancePoll
-> File GovernancePoll 'In
-> IO (Either (FileError TextEnvelopeError) GovernancePoll)
forall a content.
HasTextEnvelope a =>
AsType a
-> File content 'In -> IO (Either (FileError TextEnvelopeError) a)
readFileTextEnvelope AsType GovernancePoll
AsGovernancePoll File GovernancePoll 'In
pollFile

    Word
choice <- case Maybe Word
maybeChoice of
      Maybe Word
Nothing -> do
        GovernancePoll -> ExceptT GovernanceCmdError IO Word
askInteractively GovernancePoll
poll
      Just Word
ix -> do
        GovernancePoll -> Word -> ExceptT GovernanceCmdError IO ()
validateChoice GovernancePoll
poll Word
ix
        IO () -> ExceptT GovernanceCmdError IO ()
forall a. IO a -> ExceptT GovernanceCmdError IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ExceptT GovernanceCmdError IO ())
-> IO () -> ExceptT GovernanceCmdError IO ()
forall a b. (a -> b) -> a -> b
$
          Handle -> ByteString -> IO ()
BSC.hPutStrLn Handle
stderr (ByteString -> IO ()) -> ByteString -> IO ()
forall a b. (a -> b) -> a -> b
$
            Text -> ByteString
Text.encodeUtf8 (Text -> ByteString) -> Text -> ByteString
forall a b. (a -> b) -> a -> b
$
              Text -> [Text] -> Text
Text.intercalate
                Text
"\n"
                [ GovernancePoll -> Text
govPollQuestion GovernancePoll
poll
                , Text
"→ " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (GovernancePoll -> [Text]
govPollAnswers GovernancePoll
poll [Text] -> Int -> Text
forall a. HasCallStack => [a] -> Int -> a
!! Word -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word
ix)
                , Text
""
                ]
        Word -> ExceptT GovernanceCmdError IO Word
forall a. a -> ExceptT GovernanceCmdError IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Word
ix

    let pollAnswer :: GovernancePollAnswer
pollAnswer =
          GovernancePollAnswer
            { govAnsPoll :: Hash GovernancePoll
govAnsPoll = GovernancePoll -> Hash GovernancePoll
hashGovernancePoll GovernancePoll
poll
            , govAnsChoice :: Word
govAnsChoice = Word
choice
            }
    let metadata :: Value
metadata =
          TxMetadataJsonSchema -> TxMetadata -> Value
metadataToJson TxMetadataJsonSchema
TxMetadataJsonDetailedSchema (GovernancePollAnswer -> TxMetadata
forall a. AsTxMetadata a => a -> TxMetadata
asTxMetadata GovernancePollAnswer
pollAnswer)

    IO () -> ExceptT GovernanceCmdError IO ()
forall a. IO a -> ExceptT GovernanceCmdError IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ExceptT GovernanceCmdError IO ())
-> IO () -> ExceptT GovernanceCmdError IO ()
forall a b. (a -> b) -> a -> b
$
      Handle -> ByteString -> IO ()
BSC.hPutStrLn Handle
stderr (ByteString -> IO ()) -> ByteString -> IO ()
forall a b. (a -> b) -> a -> b
$
        [ByteString] -> ByteString
forall a. Monoid a => [a] -> a
mconcat
          [ ByteString
"Poll answer created successfully.\n"
          , ByteString
"Please submit a transaction using the resulting metadata.\n"
          , ByteString
"To be valid, the transaction must also be signed using a valid key\n"
          , ByteString
"identifying your stake pool (e.g. your cold key).\n"
          ]

    IO (Either (FileError ()) ())
-> ExceptT GovernanceCmdError IO (Either (FileError ()) ())
forall (m :: * -> *) a.
Monad m =>
m a -> ExceptT GovernanceCmdError m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Maybe (File () 'Out) -> ByteString -> IO (Either (FileError ()) ())
forall (m :: * -> *) content e.
MonadIO m =>
Maybe (File content 'Out)
-> ByteString -> m (Either (FileError e) ())
writeByteStringOutput Maybe (File () 'Out)
mOutFile (Value -> ByteString
forall a. ToJSON a => a -> ByteString
prettyPrintJSON Value
metadata))
      ExceptT GovernanceCmdError IO (Either (FileError ()) ())
-> (ExceptT GovernanceCmdError IO (Either (FileError ()) ())
    -> ExceptT GovernanceCmdError IO ())
-> ExceptT GovernanceCmdError IO ()
forall a b. a -> (a -> b) -> b
& (FileError () -> ExceptT GovernanceCmdError IO ())
-> ExceptT GovernanceCmdError IO (Either (FileError ()) ())
-> ExceptT GovernanceCmdError IO ()
forall e x (m :: * -> *) a.
Monad m =>
(e -> ExceptT x m a) -> ExceptT x m (Either e a) -> ExceptT x m a
onLeft (GovernanceCmdError -> ExceptT GovernanceCmdError IO ()
forall (m :: * -> *) x a. Monad m => x -> ExceptT x m a
left (GovernanceCmdError -> ExceptT GovernanceCmdError IO ())
-> (FileError () -> GovernanceCmdError)
-> FileError ()
-> ExceptT GovernanceCmdError IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FileError () -> GovernanceCmdError
GovernanceCmdWriteFileError)

    IO () -> ExceptT GovernanceCmdError IO ()
forall a. IO a -> ExceptT GovernanceCmdError IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ExceptT GovernanceCmdError IO ())
-> IO () -> ExceptT GovernanceCmdError IO ()
forall a b. (a -> b) -> a -> b
$
      Handle -> ByteString -> IO ()
BSC.hPutStrLn Handle
stderr (ByteString -> IO ()) -> ByteString -> IO ()
forall a b. (a -> b) -> a -> b
$
        [ByteString] -> ByteString
forall a. Monoid a => [a] -> a
mconcat
          [ ByteString
"\n"
          , ByteString
"Hint (1): Use '--json-metadata-detailed-schema' and '--metadata-json-file' "
          , ByteString
"from the build or build-raw commands.\n"
          , ByteString
"Hint (2): You can redirect the standard output of this command to a JSON "
          , ByteString
"file to capture metadata."
          ]
   where
    validateChoice :: GovernancePoll -> Word -> ExceptT GovernanceCmdError IO ()
    validateChoice :: GovernancePoll -> Word -> ExceptT GovernanceCmdError IO ()
validateChoice GovernancePoll{[Text]
govPollAnswers :: GovernancePoll -> [Text]
govPollAnswers :: [Text]
govPollAnswers} Word
ix = do
      let maxAnswerIndex :: Int
maxAnswerIndex = [Text] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Text]
govPollAnswers Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
          ixInt :: Int
ixInt = Word -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word
ix
      Bool
-> ExceptT GovernanceCmdError IO ()
-> ExceptT GovernanceCmdError IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
ixInt Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
|| Int
ixInt Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
maxAnswerIndex) (ExceptT GovernanceCmdError IO ()
 -> ExceptT GovernanceCmdError IO ())
-> ExceptT GovernanceCmdError IO ()
-> ExceptT GovernanceCmdError IO ()
forall a b. (a -> b) -> a -> b
$
        GovernanceCmdError -> ExceptT GovernanceCmdError IO ()
forall (m :: * -> *) x a. Monad m => x -> ExceptT x m a
left (GovernanceCmdError -> ExceptT GovernanceCmdError IO ())
-> GovernanceCmdError -> ExceptT GovernanceCmdError IO ()
forall a b. (a -> b) -> a -> b
$
          Int -> GovernanceCmdError
GovernanceCmdPollOutOfBoundAnswer Int
maxAnswerIndex

    askInteractively :: GovernancePoll -> ExceptT GovernanceCmdError IO Word
    askInteractively :: GovernancePoll -> ExceptT GovernanceCmdError IO Word
askInteractively poll :: GovernancePoll
poll@GovernancePoll{Text
govPollQuestion :: GovernancePoll -> Text
govPollQuestion :: Text
govPollQuestion, [Text]
govPollAnswers :: GovernancePoll -> [Text]
govPollAnswers :: [Text]
govPollAnswers} = do
      IO () -> ExceptT GovernanceCmdError IO ()
forall a. IO a -> ExceptT GovernanceCmdError IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ExceptT GovernanceCmdError IO ())
-> IO () -> ExceptT GovernanceCmdError IO ()
forall a b. (a -> b) -> a -> b
$
        Handle -> ByteString -> IO ()
BSC.hPutStrLn Handle
stderr (ByteString -> IO ()) -> ByteString -> IO ()
forall a b. (a -> b) -> a -> b
$
          Text -> ByteString
Text.encodeUtf8 (Text -> ByteString) -> Text -> ByteString
forall a b. (a -> b) -> a -> b
$
            Text -> [Text] -> Text
Text.intercalate
              Text
"\n"
              ( Text
govPollQuestion
                  Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: [ Text
"[" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall a. Show a => a -> Text
textShow Int
ix Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"] " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
answer
                    | (Int
ix :: Int, Text
answer) <- [Int] -> [Text] -> [(Int, Text)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0 ..] [Text]
govPollAnswers
                    ]
              )
      IO () -> ExceptT GovernanceCmdError IO ()
forall a. IO a -> ExceptT GovernanceCmdError IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ExceptT GovernanceCmdError IO ())
-> IO () -> ExceptT GovernanceCmdError IO ()
forall a b. (a -> b) -> a -> b
$ Handle -> ByteString -> IO ()
BSC.hPutStrLn Handle
stderr ByteString
""
      IO () -> ExceptT GovernanceCmdError IO ()
forall a. IO a -> ExceptT GovernanceCmdError IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ExceptT GovernanceCmdError IO ())
-> IO () -> ExceptT GovernanceCmdError IO ()
forall a b. (a -> b) -> a -> b
$ Handle -> ByteString -> IO ()
BSC.hPutStr Handle
stderr ByteString
"Please indicate an answer (by index): "
      Text
txt <- IO Text -> ExceptT GovernanceCmdError IO Text
forall a. IO a -> ExceptT GovernanceCmdError IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Text -> ExceptT GovernanceCmdError IO Text)
-> IO Text -> ExceptT GovernanceCmdError IO Text
forall a b. (a -> b) -> a -> b
$ Handle -> IO Text
Text.hGetLine Handle
stdin
      IO () -> ExceptT GovernanceCmdError IO ()
forall a. IO a -> ExceptT GovernanceCmdError IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ExceptT GovernanceCmdError IO ())
-> IO () -> ExceptT GovernanceCmdError IO ()
forall a b. (a -> b) -> a -> b
$ Handle -> ByteString -> IO ()
BSC.hPutStrLn Handle
stderr ByteString
""
      case Reader Word
forall a. Integral a => Reader a
Text.decimal Text
txt of
        Right (Word
choice, Text
rest)
          | Text -> Bool
Text.null Text
rest ->
              Word
choice Word
-> ExceptT GovernanceCmdError IO ()
-> ExceptT GovernanceCmdError IO Word
forall a b.
a
-> ExceptT GovernanceCmdError IO b
-> ExceptT GovernanceCmdError IO a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ GovernancePoll -> Word -> ExceptT GovernanceCmdError IO ()
validateChoice GovernancePoll
poll Word
choice
        Either String (Word, Text)
_ ->
          GovernanceCmdError -> ExceptT GovernanceCmdError IO Word
forall (m :: * -> *) x a. Monad m => x -> ExceptT x m a
left GovernanceCmdError
GovernanceCmdPollInvalidChoice

runGovernanceVerifyPollCmd
  :: ()
  => Cmd.GovernanceVerifyPollCmdArgs era
  -> ExceptT GovernanceCmdError IO ()
runGovernanceVerifyPollCmd :: forall era.
GovernanceVerifyPollCmdArgs era -> ExceptT GovernanceCmdError IO ()
runGovernanceVerifyPollCmd
  Cmd.GovernanceVerifyPollCmdArgs
    { eon :: forall era.
GovernanceVerifyPollCmdArgs era -> BabbageEraOnwards era
eon = BabbageEraOnwards era
_eon
    , pollFile :: forall era.
GovernanceVerifyPollCmdArgs era -> File GovernancePoll 'In
pollFile = File GovernancePoll 'In
pollFile
    , txFile :: forall era. GovernanceVerifyPollCmdArgs era -> File (Tx ()) 'In
txFile = File (Tx ()) 'In
txFile
    , mOutFile :: forall era. GovernanceVerifyPollCmdArgs era -> Maybe (File () 'Out)
mOutFile = Maybe (File () 'Out)
mOutFile
    } = do
    GovernancePoll
poll <-
      (FileError TextEnvelopeError -> GovernanceCmdError)
-> ExceptT (FileError TextEnvelopeError) IO GovernancePoll
-> ExceptT GovernanceCmdError IO GovernancePoll
forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT FileError TextEnvelopeError -> GovernanceCmdError
GovernanceCmdTextEnvReadError (ExceptT (FileError TextEnvelopeError) IO GovernancePoll
 -> ExceptT GovernanceCmdError IO GovernancePoll)
-> (IO (Either (FileError TextEnvelopeError) GovernancePoll)
    -> ExceptT (FileError TextEnvelopeError) IO GovernancePoll)
-> IO (Either (FileError TextEnvelopeError) GovernancePoll)
-> ExceptT GovernanceCmdError IO GovernancePoll
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO (Either (FileError TextEnvelopeError) GovernancePoll)
-> ExceptT (FileError TextEnvelopeError) IO GovernancePoll
forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
newExceptT (IO (Either (FileError TextEnvelopeError) GovernancePoll)
 -> ExceptT GovernanceCmdError IO GovernancePoll)
-> IO (Either (FileError TextEnvelopeError) GovernancePoll)
-> ExceptT GovernanceCmdError IO GovernancePoll
forall a b. (a -> b) -> a -> b
$
        AsType GovernancePoll
-> File GovernancePoll 'In
-> IO (Either (FileError TextEnvelopeError) GovernancePoll)
forall a content.
HasTextEnvelope a =>
AsType a
-> File content 'In -> IO (Either (FileError TextEnvelopeError) a)
readFileTextEnvelope AsType GovernancePoll
AsGovernancePoll File GovernancePoll 'In
pollFile

    FileOrPipe
txFileOrPipe <- IO FileOrPipe -> ExceptT GovernanceCmdError IO FileOrPipe
forall a. IO a -> ExceptT GovernanceCmdError IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO FileOrPipe -> ExceptT GovernanceCmdError IO FileOrPipe)
-> IO FileOrPipe -> ExceptT GovernanceCmdError IO FileOrPipe
forall a b. (a -> b) -> a -> b
$ String -> IO FileOrPipe
fileOrPipe (File (Tx ()) 'In -> String
forall content (direction :: FileDirection).
File content direction -> String
unFile File (Tx ()) 'In
txFile)
    InAnyShelleyBasedEra Tx
tx <-
      (FileError TextEnvelopeCddlError -> GovernanceCmdError)
-> ExceptT
     (FileError TextEnvelopeCddlError) IO (InAnyShelleyBasedEra Tx)
-> ExceptT GovernanceCmdError IO (InAnyShelleyBasedEra Tx)
forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT FileError TextEnvelopeCddlError -> GovernanceCmdError
GovernanceCmdTextEnvCddlReadError (ExceptT
   (FileError TextEnvelopeCddlError) IO (InAnyShelleyBasedEra Tx)
 -> ExceptT GovernanceCmdError IO (InAnyShelleyBasedEra Tx))
-> (IO
      (Either
         (FileError TextEnvelopeCddlError) (InAnyShelleyBasedEra Tx))
    -> ExceptT
         (FileError TextEnvelopeCddlError) IO (InAnyShelleyBasedEra Tx))
-> IO
     (Either
        (FileError TextEnvelopeCddlError) (InAnyShelleyBasedEra Tx))
-> ExceptT GovernanceCmdError IO (InAnyShelleyBasedEra Tx)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO
  (Either
     (FileError TextEnvelopeCddlError) (InAnyShelleyBasedEra Tx))
-> ExceptT
     (FileError TextEnvelopeCddlError) IO (InAnyShelleyBasedEra Tx)
forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
newExceptT (IO
   (Either
      (FileError TextEnvelopeCddlError) (InAnyShelleyBasedEra Tx))
 -> ExceptT GovernanceCmdError IO (InAnyShelleyBasedEra Tx))
-> IO
     (Either
        (FileError TextEnvelopeCddlError) (InAnyShelleyBasedEra Tx))
-> ExceptT GovernanceCmdError IO (InAnyShelleyBasedEra Tx)
forall a b. (a -> b) -> a -> b
$
        FileOrPipe
-> IO
     (Either
        (FileError TextEnvelopeCddlError) (InAnyShelleyBasedEra Tx))
readFileTx FileOrPipe
txFileOrPipe

    [Hash PaymentKey]
signatories <-
      (GovernancePollError -> GovernanceCmdError)
-> ExceptT GovernancePollError IO [Hash PaymentKey]
-> ExceptT GovernanceCmdError IO [Hash PaymentKey]
forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT GovernancePollError -> GovernanceCmdError
GovernanceCmdVerifyPollError (ExceptT GovernancePollError IO [Hash PaymentKey]
 -> ExceptT GovernanceCmdError IO [Hash PaymentKey])
-> (IO (Either GovernancePollError [Hash PaymentKey])
    -> ExceptT GovernancePollError IO [Hash PaymentKey])
-> IO (Either GovernancePollError [Hash PaymentKey])
-> ExceptT GovernanceCmdError IO [Hash PaymentKey]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO (Either GovernancePollError [Hash PaymentKey])
-> ExceptT GovernancePollError IO [Hash PaymentKey]
forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
newExceptT (IO (Either GovernancePollError [Hash PaymentKey])
 -> ExceptT GovernanceCmdError IO [Hash PaymentKey])
-> IO (Either GovernancePollError [Hash PaymentKey])
-> ExceptT GovernanceCmdError IO [Hash PaymentKey]
forall a b. (a -> b) -> a -> b
$
        Either GovernancePollError [Hash PaymentKey]
-> IO (Either GovernancePollError [Hash PaymentKey])
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either GovernancePollError [Hash PaymentKey]
 -> IO (Either GovernancePollError [Hash PaymentKey]))
-> Either GovernancePollError [Hash PaymentKey]
-> IO (Either GovernancePollError [Hash PaymentKey])
forall a b. (a -> b) -> a -> b
$
          GovernancePoll
-> InAnyShelleyBasedEra Tx
-> Either GovernancePollError [Hash PaymentKey]
verifyPollAnswer GovernancePoll
poll InAnyShelleyBasedEra Tx
tx

    IO () -> ExceptT GovernanceCmdError IO ()
forall a. IO a -> ExceptT GovernanceCmdError IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ExceptT GovernanceCmdError IO ())
-> IO () -> ExceptT GovernanceCmdError IO ()
forall a b. (a -> b) -> a -> b
$
      Handle -> String -> IO ()
IO.hPutStrLn Handle
stderr (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$
        String
"Found valid poll answer with " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show ([Hash PaymentKey] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Hash PaymentKey]
signatories) String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
" signatories"

    IO (Either (FileError ()) ())
-> ExceptT GovernanceCmdError IO (Either (FileError ()) ())
forall (m :: * -> *) a.
Monad m =>
m a -> ExceptT GovernanceCmdError m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Maybe (File () 'Out) -> ByteString -> IO (Either (FileError ()) ())
forall (m :: * -> *) content e.
MonadIO m =>
Maybe (File content 'Out)
-> ByteString -> m (Either (FileError e) ())
writeByteStringOutput Maybe (File () 'Out)
mOutFile ([Hash PaymentKey] -> ByteString
forall a. ToJSON a => a -> ByteString
prettyPrintJSON [Hash PaymentKey]
signatories))
      ExceptT GovernanceCmdError IO (Either (FileError ()) ())
-> (ExceptT GovernanceCmdError IO (Either (FileError ()) ())
    -> ExceptT GovernanceCmdError IO ())
-> ExceptT GovernanceCmdError IO ()
forall a b. a -> (a -> b) -> b
& (FileError () -> ExceptT GovernanceCmdError IO ())
-> ExceptT GovernanceCmdError IO (Either (FileError ()) ())
-> ExceptT GovernanceCmdError IO ()
forall e x (m :: * -> *) a.
Monad m =>
(e -> ExceptT x m a) -> ExceptT x m (Either e a) -> ExceptT x m a
onLeft (GovernanceCmdError -> ExceptT GovernanceCmdError IO ()
forall (m :: * -> *) x a. Monad m => x -> ExceptT x m a
left (GovernanceCmdError -> ExceptT GovernanceCmdError IO ())
-> (FileError () -> GovernanceCmdError)
-> FileError ()
-> ExceptT GovernanceCmdError IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FileError () -> GovernanceCmdError
GovernanceCmdWriteFileError)