{-# 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
  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
  proposal <- readByronUpdateProposal upPropFp
  let vote = NetworkId
-> SomeByronSigningKey -> ByronUpdateProposal -> Bool -> ByronVote
makeByronVote NetworkId
nw SomeByronSigningKey
sK ByronUpdateProposal
proposal Bool
voteBool
  fromExceptTCli . ensureNewFileLBS outputFp $
    serialiseToRawBytes vote

submitByronVote
  :: SocketPath
  -> NetworkId
  -> FilePath
  -> CIO e ()
submitByronVote :: forall e. SocketPath -> NetworkId -> FilePath -> CIO e ()
submitByronVote SocketPath
nodeSocketPath NetworkId
network FilePath
voteFp = do
  vote <- FilePath -> CIO e ByronVote
forall e. FilePath -> CIO e ByronVote
readByronVote FilePath
voteFp
  let genTx = ByronVote -> GenTx ByronBlock
toByronLedgertoByronVote ByronVote
vote
  traceWith stdoutTracer ("Vote TxId: " ++ condense (txId genTx))
  fromExceptTCli $ nodeSubmitTx nodeSocketPath network genTx

readByronVote :: FilePath -> CIO e ByronVote
readByronVote :: forall e. FilePath -> CIO e ByronVote
readByronVote FilePath
fp = do
  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 = AsType ByronVote
-> ByteString -> Either SerialiseAsRawBytesError ByronVote
forall a.
SerialiseAsRawBytes a =>
AsType a -> ByteString -> Either SerialiseAsRawBytesError a
deserialiseFromRawBytes AsType ByronVote
AsByronVote ByteString
voteBs
  fromEitherCli voteResult