{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE RankNTypes #-}

module Cardano.CLI.Byron.Vote
  ( readByronVote
  , runVoteCreation
  , submitByronVote
  )
where

import Cardano.Api
  ( SocketPath
  , deserialiseFromRawBytes
  , liftIO
  , serialiseToRawBytes
  )
import Cardano.Api.Byron
import Cardano.Api.Consensus (condense, txId)

import Cardano.CLI.Byron.Key (readByronSigningKey)
import Cardano.CLI.Byron.Tx (nodeSubmitTx)
import Cardano.CLI.Byron.UpdateProposal
  ( readByronUpdateProposal
  )
import Cardano.CLI.Compatible.Exception
import Cardano.CLI.Helper (ensureNewFileLBS)
import Cardano.CLI.Type.Common

import Control.Tracer (stdoutTracer, traceWith)
import Data.ByteString qualified as BS

runVoteCreation
  :: NetworkId
  -> SigningKeyFile In
  -> FilePath
  -> Bool
  -> FilePath
  -> CIO e ()
runVoteCreation :: forall e.
NetworkId
-> SigningKeyFile 'In -> FilePath -> Bool -> FilePath -> CIO e ()
runVoteCreation NetworkId
nw SigningKeyFile 'In
sKey FilePath
upPropFp Bool
voteBool FilePath
outputFp = do
  SomeByronSigningKey
sK <- ExceptT ByronKeyFailure IO SomeByronSigningKey
-> RIO e SomeByronSigningKey
forall e (m :: * -> *) a.
(HasCallStack, MonadIO m, Show e, Typeable e, Error e) =>
ExceptT e IO a -> m a
fromExceptTCli (ExceptT ByronKeyFailure IO SomeByronSigningKey
 -> RIO e SomeByronSigningKey)
-> ExceptT ByronKeyFailure IO SomeByronSigningKey
-> RIO e SomeByronSigningKey
forall a b. (a -> b) -> a -> b
$ ByronKeyFormat
-> SigningKeyFile 'In
-> ExceptT ByronKeyFailure IO SomeByronSigningKey
readByronSigningKey ByronKeyFormat
NonLegacyByronKeyFormat SigningKeyFile 'In
sKey
  ByronUpdateProposal
proposal <- FilePath -> CIO e ByronUpdateProposal
forall e. FilePath -> CIO e ByronUpdateProposal
readByronUpdateProposal FilePath
upPropFp
  let vote :: ByronVote
vote = NetworkId
-> SomeByronSigningKey -> ByronUpdateProposal -> Bool -> ByronVote
makeByronVote NetworkId
nw SomeByronSigningKey
sK ByronUpdateProposal
proposal Bool
voteBool
  ExceptT HelpersError IO () -> RIO e ()
forall e (m :: * -> *) a.
(HasCallStack, MonadIO m, Show e, Typeable e, Error e) =>
ExceptT e IO a -> m a
fromExceptTCli (ExceptT HelpersError IO () -> RIO e ())
-> (ByteString -> ExceptT HelpersError IO ())
-> ByteString
-> RIO e ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> ByteString -> ExceptT HelpersError IO ()
ensureNewFileLBS FilePath
outputFp (ByteString -> RIO e ()) -> ByteString -> RIO e ()
forall a b. (a -> b) -> a -> b
$
    ByronVote -> ByteString
forall a. SerialiseAsRawBytes a => a -> ByteString
serialiseToRawBytes ByronVote
vote

submitByronVote
  :: SocketPath
  -> NetworkId
  -> FilePath
  -> CIO e ()
submitByronVote :: forall e. SocketPath -> NetworkId -> FilePath -> CIO e ()
submitByronVote SocketPath
nodeSocketPath NetworkId
network FilePath
voteFp = do
  ByronVote
vote <- FilePath -> CIO e ByronVote
forall e. FilePath -> CIO e ByronVote
readByronVote FilePath
voteFp
  let genTx :: GenTx ByronBlock
genTx = ByronVote -> GenTx ByronBlock
toByronLedgertoByronVote ByronVote
vote
  Tracer (RIO e) FilePath -> FilePath -> RIO e ()
forall (m :: * -> *) a. Tracer m a -> a -> m ()
traceWith Tracer (RIO e) FilePath
forall (m :: * -> *). MonadIO m => Tracer m FilePath
stdoutTracer (FilePath
"Vote TxId: " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ TxId (GenTx ByronBlock) -> FilePath
forall a. Condense a => a -> FilePath
condense (GenTx ByronBlock -> TxId (GenTx ByronBlock)
forall tx. HasTxId tx => tx -> TxId tx
txId GenTx ByronBlock
genTx))
  ExceptT ByronTxError IO () -> RIO e ()
forall e (m :: * -> *) a.
(HasCallStack, MonadIO m, Show e, Typeable e, Error e) =>
ExceptT e IO a -> m a
fromExceptTCli (ExceptT ByronTxError IO () -> RIO e ())
-> ExceptT ByronTxError IO () -> RIO e ()
forall a b. (a -> b) -> a -> b
$ SocketPath
-> NetworkId -> GenTx ByronBlock -> ExceptT ByronTxError IO ()
nodeSubmitTx SocketPath
nodeSocketPath NetworkId
network GenTx ByronBlock
genTx

readByronVote :: FilePath -> CIO e ByronVote
readByronVote :: forall e. FilePath -> CIO e ByronVote
readByronVote FilePath
fp = do
  ByteString
voteBs <- IO ByteString -> RIO e ByteString
forall a. IO a -> RIO e a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ByteString -> RIO e ByteString)
-> IO ByteString -> RIO e ByteString
forall a b. (a -> b) -> a -> b
$ FilePath -> IO ByteString
BS.readFile FilePath
fp
  let voteResult :: Either SerialiseAsRawBytesError ByronVote
voteResult = AsType ByronVote
-> ByteString -> Either SerialiseAsRawBytesError ByronVote
forall a.
SerialiseAsRawBytes a =>
AsType a -> ByteString -> Either SerialiseAsRawBytesError a
deserialiseFromRawBytes AsType ByronVote
AsByronVote ByteString
voteBs
  Either SerialiseAsRawBytesError ByronVote -> RIO e ByronVote
forall e (m :: * -> *) a.
(HasCallStack, MonadIO m, Show e, Typeable e, Error e) =>
Either e a -> m a
fromEitherCli Either SerialiseAsRawBytesError ByronVote
voteResult