module DMQ.Configuration.CLIOptions (parseCLIOptions) where

import Data.Monoid (Last (..))
import Options.Applicative

import DMQ.Configuration

parseCLIOptions :: Parser PartialConfig
parseCLIOptions :: Parser PartialConfig
parseCLIOptions =
  Maybe IPv4
-> Maybe IPv6
-> Maybe PortNumber
-> Maybe FilePath
-> Maybe FilePath
-> PartialConfig
mkConfiguration
    (Maybe IPv4
 -> Maybe IPv6
 -> Maybe PortNumber
 -> Maybe FilePath
 -> Maybe FilePath
 -> PartialConfig)
-> Parser (Maybe IPv4)
-> Parser
     (Maybe IPv6
      -> Maybe PortNumber
      -> Maybe FilePath
      -> Maybe FilePath
      -> PartialConfig)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser IPv4 -> Parser (Maybe IPv4)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (
          ReadM IPv4 -> Mod OptionFields IPv4 -> Parser IPv4
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM IPv4
forall a. Read a => ReadM a
auto
          (  FilePath -> Mod OptionFields IPv4
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"host-addr"
          Mod OptionFields IPv4
-> Mod OptionFields IPv4 -> Mod OptionFields IPv4
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields IPv4
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"IPv4"
          Mod OptionFields IPv4
-> Mod OptionFields IPv4 -> Mod OptionFields IPv4
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields IPv4
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"IPv4 that the node will bind to"
          )
        )
    Parser
  (Maybe IPv6
   -> Maybe PortNumber
   -> Maybe FilePath
   -> Maybe FilePath
   -> PartialConfig)
-> Parser (Maybe IPv6)
-> Parser
     (Maybe PortNumber
      -> Maybe FilePath -> Maybe FilePath -> PartialConfig)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser IPv6 -> Parser (Maybe IPv6)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (
          ReadM IPv6 -> Mod OptionFields IPv6 -> Parser IPv6
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM IPv6
forall a. Read a => ReadM a
auto
           (  FilePath -> Mod OptionFields IPv6
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"host-ipv6-addr"
           Mod OptionFields IPv6
-> Mod OptionFields IPv6 -> Mod OptionFields IPv6
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields IPv6
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"IPv6"
           Mod OptionFields IPv6
-> Mod OptionFields IPv6 -> Mod OptionFields IPv6
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields IPv6
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"IPv6 that the node will bind to"
           )
        )
    Parser
  (Maybe PortNumber
   -> Maybe FilePath -> Maybe FilePath -> PartialConfig)
-> Parser (Maybe PortNumber)
-> Parser (Maybe FilePath -> Maybe FilePath -> PartialConfig)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser PortNumber -> Parser (Maybe PortNumber)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (
          ReadM PortNumber
-> Mod OptionFields PortNumber -> Parser PortNumber
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM PortNumber
forall a. Read a => ReadM a
auto
          (  FilePath -> Mod OptionFields PortNumber
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"port"
          Mod OptionFields PortNumber
-> Mod OptionFields PortNumber -> Mod OptionFields PortNumber
forall a. Semigroup a => a -> a -> a
<> Char -> Mod OptionFields PortNumber
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'p'
          Mod OptionFields PortNumber
-> Mod OptionFields PortNumber -> Mod OptionFields PortNumber
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields PortNumber
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"Port Number"
          Mod OptionFields PortNumber
-> Mod OptionFields PortNumber -> Mod OptionFields PortNumber
forall a. Semigroup a => a -> a -> a
<> FilePath -> Mod OptionFields PortNumber
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Port Number that the node will bind to"
          )
        )
    Parser (Maybe FilePath -> Maybe FilePath -> PartialConfig)
-> Parser (Maybe FilePath)
-> Parser (Maybe FilePath -> PartialConfig)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser FilePath -> Parser (Maybe FilePath)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (
          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
"configuration-file"
          Mod OptionFields FilePath
-> Mod OptionFields FilePath -> Mod OptionFields FilePath
forall a. Semigroup a => a -> a -> a
<> Char -> Mod OptionFields FilePath
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'c'
          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
"FILENAME"
          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
"Configuration file for DMQ Node"
          )
        )
    Parser (Maybe FilePath -> PartialConfig)
-> Parser (Maybe FilePath) -> Parser PartialConfig
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser FilePath -> Parser (Maybe FilePath)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (
          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
"topology-file"
          Mod OptionFields FilePath
-> Mod OptionFields FilePath -> Mod OptionFields FilePath
forall a. Semigroup a => a -> a -> a
<> Char -> Mod OptionFields FilePath
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
't'
          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
"FILENAME"
          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
"Topology file for DMQ Node"
          )
        )
  where
    mkConfiguration :: Maybe IPv4
-> Maybe IPv6
-> Maybe PortNumber
-> Maybe FilePath
-> Maybe FilePath
-> PartialConfig
mkConfiguration Maybe IPv4
ipv4 Maybe IPv6
ipv6 Maybe PortNumber
portNumber Maybe FilePath
configFile Maybe FilePath
topologyFile =
      PartialConfig
forall a. Monoid a => a
mempty { dmqcIPv4 = Last (Just <$> ipv4),
               dmqcIPv6 = Last (Just <$> ipv6),
               dmqcPortNumber = Last portNumber,
               dmqcConfigFile = Last configFile,
               dmqcTopologyFile = Last topologyFile
             }