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

module Cardano.CLI.EraIndependent.Cip.Common
  ( -- * Input related
    Input (..)
  , InputError (..)
  , pInputFile
  , pInputHexText
  , pInputBech32Text

    -- * Output related
  , Output (..)
  , pOutputFile
  , pOutputText
  )
where

import Cardano.Api

import Cardano.CLI.EraBased.Common.Option hiding (pOutputFile)

import Data.Text (Text)
import Data.Text qualified as Text
import Options.Applicative qualified as Opt

data Input
  = InputTextEnvelopeFile (File () In)
  | InputHexText Text
  | InputBech32Text Text

newtype InputError = InputError Text deriving Int -> InputError -> ShowS
[InputError] -> ShowS
InputError -> String
(Int -> InputError -> ShowS)
-> (InputError -> String)
-> ([InputError] -> ShowS)
-> Show InputError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> InputError -> ShowS
showsPrec :: Int -> InputError -> ShowS
$cshow :: InputError -> String
show :: InputError -> String
$cshowList :: [InputError] -> ShowS
showList :: [InputError] -> ShowS
Show

instance Error InputError where
  prettyError :: forall ann. InputError -> Doc ann
prettyError (InputError Text
err) = Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Text -> Doc ann
pretty Text
err

pInputFile :: String -> String -> Opt.Parser Input
pInputFile :: String -> String -> Parser Input
pInputFile String
optName String
desc =
  File () 'In -> Input
InputTextEnvelopeFile (File () 'In -> Input) -> Parser (File () 'In) -> Parser Input
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> String -> Parser (File () 'In)
forall a. String -> String -> Parser (File a 'In)
pFileInDirection String
optName String
desc

pInputHexText :: String -> String -> String -> Opt.Parser Input
pInputHexText :: String -> String -> String -> Parser Input
pInputHexText String
optName String
metavar String
help =
  (String -> Input) -> Parser String -> Parser Input
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Text -> Input
InputHexText (Text -> Input) -> (String -> Text) -> String -> Input
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
Text.pack) (Parser String -> Parser Input) -> Parser String -> Parser Input
forall a b. (a -> b) -> a -> b
$
    Mod OptionFields String -> Parser String
forall s. IsString s => Mod OptionFields s -> Parser s
Opt.strOption (Mod OptionFields String -> Parser String)
-> Mod OptionFields String -> Parser String
forall a b. (a -> b) -> a -> b
$
      [Mod OptionFields String] -> Mod OptionFields String
forall a. Monoid a => [a] -> a
mconcat
        [ String -> Mod OptionFields String
forall (f :: * -> *) a. HasName f => String -> Mod f a
Opt.long String
optName
        , String -> Mod OptionFields String
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
Opt.metavar String
metavar
        , String -> Mod OptionFields String
forall (f :: * -> *) a. String -> Mod f a
Opt.help String
help
        ]

pInputBech32Text :: String -> String -> String -> Opt.Parser Input
pInputBech32Text :: String -> String -> String -> Parser Input
pInputBech32Text String
optName String
metavar String
help =
  (String -> Input) -> Parser String -> Parser Input
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Text -> Input
InputBech32Text (Text -> Input) -> (String -> Text) -> String -> Input
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
Text.pack) (Parser String -> Parser Input) -> Parser String -> Parser Input
forall a b. (a -> b) -> a -> b
$
    Mod OptionFields String -> Parser String
forall s. IsString s => Mod OptionFields s -> Parser s
Opt.strOption (Mod OptionFields String -> Parser String)
-> Mod OptionFields String -> Parser String
forall a b. (a -> b) -> a -> b
$
      [Mod OptionFields String] -> Mod OptionFields String
forall a. Monoid a => [a] -> a
mconcat
        [ String -> Mod OptionFields String
forall (f :: * -> *) a. HasName f => String -> Mod f a
Opt.long String
optName
        , String -> Mod OptionFields String
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
Opt.metavar String
metavar
        , String -> Mod OptionFields String
forall (f :: * -> *) a. String -> Mod f a
Opt.help String
help
        ]

data Output
  = OutputFile (File () Out)
  | OutputText

pOutputFile :: String -> String -> Opt.Parser Output
pOutputFile :: String -> String -> Parser Output
pOutputFile String
optName String
desc =
  File () 'Out -> Output
OutputFile (File () 'Out -> Output) -> Parser (File () 'Out) -> Parser Output
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> String -> Parser (File () 'Out)
forall a. String -> String -> Parser (File a 'Out)
pFileOutDirection String
optName String
desc

pOutputText :: String -> String -> Opt.Parser Output
pOutputText :: String -> String -> Parser Output
pOutputText String
optName String
help =
  Output -> Mod FlagFields Output -> Parser Output
forall a. a -> Mod FlagFields a -> Parser a
Opt.flag' Output
OutputText (Mod FlagFields Output -> Parser Output)
-> Mod FlagFields Output -> Parser Output
forall a b. (a -> b) -> a -> b
$
    [Mod FlagFields Output] -> Mod FlagFields Output
forall a. Monoid a => [a] -> a
mconcat
      [ String -> Mod FlagFields Output
forall (f :: * -> *) a. HasName f => String -> Mod f a
Opt.long String
optName
      , String -> Mod FlagFields Output
forall (f :: * -> *) a. String -> Mod f a
Opt.help String
help
      ]