module Bcc.CLI.Sophie.Run.TextView
  ( SophieTextViewFileError(..)
  , renderSophieTextViewFileError
  , runTextViewCmd
  ) where

import           Bcc.Prelude

import qualified Data.Text as Text

import           Bcc.CLI.Helpers (HelpersError, pPrintCBOR, renderHelpersError)
import           Bcc.CLI.Sophie.Parsers

import           Bcc.Api

import           Control.Monad.Trans.Except.Extra (firstExceptT, newExceptT)

import qualified Data.ByteString.Lazy.Char8 as LBS

data SophieTextViewFileError
  = TextViewReadFileError (FileError TextEnvelopeError)
  | TextViewCBORPrettyPrintError !HelpersError
  deriving Int -> SophieTextViewFileError -> ShowS
[SophieTextViewFileError] -> ShowS
SophieTextViewFileError -> String
(Int -> SophieTextViewFileError -> ShowS)
-> (SophieTextViewFileError -> String)
-> ([SophieTextViewFileError] -> ShowS)
-> Show SophieTextViewFileError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SophieTextViewFileError] -> ShowS
$cshowList :: [SophieTextViewFileError] -> ShowS
show :: SophieTextViewFileError -> String
$cshow :: SophieTextViewFileError -> String
showsPrec :: Int -> SophieTextViewFileError -> ShowS
$cshowsPrec :: Int -> SophieTextViewFileError -> ShowS
Show

renderSophieTextViewFileError :: SophieTextViewFileError -> Text
renderSophieTextViewFileError :: SophieTextViewFileError -> Text
renderSophieTextViewFileError SophieTextViewFileError
err =
  case SophieTextViewFileError
err of
    TextViewReadFileError FileError TextEnvelopeError
fileErr -> String -> Text
Text.pack (FileError TextEnvelopeError -> String
forall e. Error e => e -> String
displayError FileError TextEnvelopeError
fileErr)
    TextViewCBORPrettyPrintError HelpersError
hlprsErr ->
      Text
"Error pretty printing CBOR: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> HelpersError -> Text
renderHelpersError HelpersError
hlprsErr


runTextViewCmd :: TextViewCmd -> ExceptT SophieTextViewFileError IO ()
runTextViewCmd :: TextViewCmd -> ExceptT SophieTextViewFileError IO ()
runTextViewCmd TextViewCmd
cmd =
  case TextViewCmd
cmd of
    TextViewInfo String
fpath Maybe OutputFile
mOutfile -> String -> Maybe OutputFile -> ExceptT SophieTextViewFileError IO ()
runTextViewInfo String
fpath Maybe OutputFile
mOutfile

runTextViewInfo :: FilePath -> Maybe OutputFile -> ExceptT SophieTextViewFileError IO ()
runTextViewInfo :: String -> Maybe OutputFile -> ExceptT SophieTextViewFileError IO ()
runTextViewInfo String
fpath Maybe OutputFile
mOutFile = do
  TextEnvelope
tv <- (FileError TextEnvelopeError -> SophieTextViewFileError)
-> ExceptT (FileError TextEnvelopeError) IO TextEnvelope
-> ExceptT SophieTextViewFileError IO TextEnvelope
forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT FileError TextEnvelopeError -> SophieTextViewFileError
TextViewReadFileError (ExceptT (FileError TextEnvelopeError) IO TextEnvelope
 -> ExceptT SophieTextViewFileError IO TextEnvelope)
-> ExceptT (FileError TextEnvelopeError) IO TextEnvelope
-> ExceptT SophieTextViewFileError IO TextEnvelope
forall a b. (a -> b) -> a -> b
$ IO (Either (FileError TextEnvelopeError) TextEnvelope)
-> ExceptT (FileError TextEnvelopeError) IO TextEnvelope
forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
newExceptT (String -> IO (Either (FileError TextEnvelopeError) TextEnvelope)
readTextEnvelopeFromFile String
fpath)
  let lbCBOR :: ByteString
lbCBOR = ByteString -> ByteString
LBS.fromStrict (TextEnvelope -> ByteString
textEnvelopeRawCBOR TextEnvelope
tv)
  case Maybe OutputFile
mOutFile of
    Just (OutputFile String
oFpath) -> IO () -> ExceptT SophieTextViewFileError IO ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ExceptT SophieTextViewFileError IO ())
-> IO () -> ExceptT SophieTextViewFileError IO ()
forall a b. (a -> b) -> a -> b
$ String -> ByteString -> IO ()
LBS.writeFile String
oFpath ByteString
lbCBOR
    Maybe OutputFile
Nothing -> (HelpersError -> SophieTextViewFileError)
-> ExceptT HelpersError IO ()
-> ExceptT SophieTextViewFileError IO ()
forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> ExceptT x m a -> ExceptT y m a
firstExceptT HelpersError -> SophieTextViewFileError
TextViewCBORPrettyPrintError (ExceptT HelpersError IO ()
 -> ExceptT SophieTextViewFileError IO ())
-> ExceptT HelpersError IO ()
-> ExceptT SophieTextViewFileError IO ()
forall a b. (a -> b) -> a -> b
$ ByteString -> ExceptT HelpersError IO ()
pPrintCBOR ByteString
lbCBOR