module Marconi.MambaCli where

import Data.Maybe (fromMaybe)
import Options.Applicative (Parser, ParserInfo, auto, execParser, fullDesc, header, help, helper, info, infoOption,
                            long, metavar, option, optional, progDesc, strOption)
import System.Environment (lookupEnv)

import Marconi.Api.Types (CliArgs (CliArgs))
import Marconi.CLI (multiString, pNetworkId)


-- | parse cli arguments
--
parserCliArgs :: Parser CliArgs
parserCliArgs :: Parser CliArgs
parserCliArgs = FilePath
-> FilePath -> Maybe Int -> NetworkId -> TargetAddresses -> CliArgs
CliArgs
  (FilePath
 -> FilePath
 -> Maybe Int
 -> NetworkId
 -> TargetAddresses
 -> CliArgs)
-> Parser FilePath
-> Parser
     (FilePath -> Maybe Int -> NetworkId -> TargetAddresses -> CliArgs)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Mod OptionFields FilePath -> Parser FilePath
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"socket-path" Mod OptionFields FilePath
-> Mod OptionFields FilePath -> Mod OptionFields FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"FILE" Mod OptionFields FilePath
-> Mod OptionFields FilePath -> Mod OptionFields FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Socket path to node")
  Parser
  (FilePath -> Maybe Int -> NetworkId -> TargetAddresses -> CliArgs)
-> Parser FilePath
-> Parser (Maybe Int -> NetworkId -> TargetAddresses -> CliArgs)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Mod OptionFields FilePath -> Parser FilePath
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"utxo-db" Mod OptionFields FilePath
-> Mod OptionFields FilePath -> Mod OptionFields FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"FILE" Mod OptionFields FilePath
-> Mod OptionFields FilePath -> Mod OptionFields FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields FilePath
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Path to the utxo database.")
  Parser (Maybe Int -> NetworkId -> TargetAddresses -> CliArgs)
-> Parser (Maybe Int)
-> Parser (NetworkId -> TargetAddresses -> CliArgs)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Parser Int -> Parser (Maybe Int)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser Int -> Parser (Maybe Int))
-> (Mod OptionFields Int -> Parser Int)
-> Mod OptionFields Int
-> Parser (Maybe Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReadM Int -> Mod OptionFields Int -> Parser Int
forall a. ReadM a -> Mod OptionFields a -> Parser a
option  ReadM Int
forall a. Read a => ReadM a
auto) (
        FilePath -> Mod OptionFields Int
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"http-port" Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields Int
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"HTTP-PORT" Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields Int
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"JSON-RPC http port number, default is port 3000.")
  Parser (NetworkId -> TargetAddresses -> CliArgs)
-> Parser NetworkId -> Parser (TargetAddresses -> CliArgs)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser NetworkId
pNetworkId
  Parser (TargetAddresses -> CliArgs)
-> Parser TargetAddresses -> Parser CliArgs
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Mod OptionFields [Address ShelleyAddr] -> Parser TargetAddresses
multiString (FilePath -> Mod OptionFields [Address ShelleyAddr]
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"addresses-to-index"
                        Mod OptionFields [Address ShelleyAddr]
-> Mod OptionFields [Address ShelleyAddr]
-> Mod OptionFields [Address ShelleyAddr]
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields [Address ShelleyAddr]
forall (f :: * -> *) a. FilePath -> Mod f a
help (FilePath
"Bech32 Shelley addresses to index."
                                 FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<> FilePath
" i.e \"--address-to-index address-1 --address-to-index address-2 ...\"" ) )

parserOpts  :: String -> ParserInfo CliArgs
parserOpts :: FilePath -> ParserInfo CliArgs
parserOpts FilePath
sha =
    Parser CliArgs -> InfoMod CliArgs -> ParserInfo CliArgs
forall a. Parser a -> InfoMod a -> ParserInfo a
info (Parser ((CliArgs -> CliArgs) -> CliArgs -> CliArgs)
forall a. Parser (a -> a)
helper
          Parser ((CliArgs -> CliArgs) -> CliArgs -> CliArgs)
-> Parser (CliArgs -> CliArgs) -> Parser (CliArgs -> CliArgs)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (CliArgs -> CliArgs)
forall a. Parser (a -> a)
versionOption
          Parser (CliArgs -> CliArgs) -> Parser CliArgs -> Parser CliArgs
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser CliArgs
parserCliArgs)
    ( InfoMod CliArgs
forall a. InfoMod a
fullDesc
      InfoMod CliArgs -> InfoMod CliArgs -> InfoMod CliArgs
forall a. Semigroup a => a -> a -> a
<> FilePath -> InfoMod CliArgs
forall a. FilePath -> InfoMod a
progDesc FilePath
"marconi-mamba"
      InfoMod CliArgs -> InfoMod CliArgs -> InfoMod CliArgs
forall a. Semigroup a => a -> a -> a
<> FilePath -> InfoMod CliArgs
forall a. FilePath -> InfoMod a
header
          FilePath
"marconi - a lightweight customizable solution for indexing and querying the Cardano blockchain"
    )
    where
        versionOption :: Parser (a -> a)
versionOption  =
            FilePath -> Mod OptionFields (a -> a) -> Parser (a -> a)
forall a. FilePath -> Mod OptionFields (a -> a) -> Parser (a -> a)
infoOption FilePath
sha (FilePath -> Mod OptionFields (a -> a)
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"version"
                            Mod OptionFields (a -> a)
-> Mod OptionFields (a -> a) -> Mod OptionFields (a -> a)
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields (a -> a)
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Show git SHA")

parseCli :: IO CliArgs
parseCli :: IO CliArgs
parseCli = do
    Maybe FilePath
maybeSha <- FilePath -> IO (Maybe FilePath)
lookupEnv FilePath
"GITHUB_SHA"
    let sha :: FilePath
sha = FilePath -> Maybe FilePath -> FilePath
forall a. a -> Maybe a -> a
fromMaybe FilePath
"GIHUB_SHA environment variable not set!" Maybe FilePath
maybeSha
    ParserInfo CliArgs -> IO CliArgs
forall a. ParserInfo a -> IO a
execParser (ParserInfo CliArgs -> IO CliArgs)
-> ParserInfo CliArgs -> IO CliArgs
forall a b. (a -> b) -> a -> b
$ FilePath -> ParserInfo CliArgs
parserOpts FilePath
sha