module Testnet.Commands.Cole
  ( ColeOptions(..)
  , cmdCole
  , runColeOptions
  ) where

import           Data.Eq
import           Data.Function
import           Data.Int
import           Data.Maybe
import           Data.Semigroup
import           Options.Applicative
import           System.IO (IO)
import           Testnet.Cole
import           Testnet.Run (runTestnet)
import           Text.Show

import qualified Options.Applicative as OA

data ColeOptions = ColeOptions
  { ColeOptions -> Maybe Int
maybeTestnetMagic :: Maybe Int
  , ColeOptions -> TestnetOptions
testnetOptions :: TestnetOptions
  } deriving (ColeOptions -> ColeOptions -> Bool
(ColeOptions -> ColeOptions -> Bool)
-> (ColeOptions -> ColeOptions -> Bool) -> Eq ColeOptions
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ColeOptions -> ColeOptions -> Bool
$c/= :: ColeOptions -> ColeOptions -> Bool
== :: ColeOptions -> ColeOptions -> Bool
$c== :: ColeOptions -> ColeOptions -> Bool
Eq, Int -> ColeOptions -> ShowS
[ColeOptions] -> ShowS
ColeOptions -> String
(Int -> ColeOptions -> ShowS)
-> (ColeOptions -> String)
-> ([ColeOptions] -> ShowS)
-> Show ColeOptions
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ColeOptions] -> ShowS
$cshowList :: [ColeOptions] -> ShowS
show :: ColeOptions -> String
$cshow :: ColeOptions -> String
showsPrec :: Int -> ColeOptions -> ShowS
$cshowsPrec :: Int -> ColeOptions -> ShowS
Show)

optsCole :: Parser ColeOptions
optsCole :: Parser ColeOptions
optsCole = Maybe Int -> TestnetOptions -> ColeOptions
ColeOptions
  (Maybe Int -> TestnetOptions -> ColeOptions)
-> Parser (Maybe Int) -> Parser (TestnetOptions -> ColeOptions)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Int -> Parser (Maybe Int)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional
      ( ReadM Int -> Mod OptionFields Int -> Parser Int
forall a. ReadM a -> Mod OptionFields a -> Parser a
OA.option ReadM Int
forall a. Read a => ReadM a
auto
        (   String -> Mod OptionFields Int
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"testnet-magic"
        Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<>  String -> Mod OptionFields Int
forall (f :: * -> *) a. String -> Mod f a
help String
"Testnet magic"
        Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<>  String -> Mod OptionFields Int
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"INT"
        )
      )
  Parser (TestnetOptions -> ColeOptions)
-> Parser TestnetOptions -> Parser ColeOptions
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser TestnetOptions
optsTestnet

optsTestnet :: Parser TestnetOptions
optsTestnet :: Parser TestnetOptions
optsTestnet = Int -> Int -> Int -> Int -> Int -> TestnetOptions
TestnetOptions
  (Int -> Int -> Int -> Int -> Int -> TestnetOptions)
-> Parser Int
-> Parser (Int -> Int -> Int -> Int -> TestnetOptions)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadM Int -> Mod OptionFields Int -> Parser Int
forall a. ReadM a -> Mod OptionFields a -> Parser a
OA.option ReadM Int
forall a. Read a => ReadM a
auto
      (   String -> Mod OptionFields Int
forall (f :: * -> *) a. HasName f => String -> Mod f a
OA.long String
"num-bft-nodes"
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<>  String -> Mod OptionFields Int
forall (f :: * -> *) a. String -> Mod f a
OA.help String
"Number of BFT nodes"
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<>  String -> Mod OptionFields Int
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
OA.metavar String
"COUNT"
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<>  Mod OptionFields Int
forall a (f :: * -> *). Show a => Mod f a
OA.showDefault
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<>  Int -> Mod OptionFields Int
forall (f :: * -> *) a. HasValue f => a -> Mod f a
OA.value (TestnetOptions -> Int
numBftNodes TestnetOptions
defaultTestnetOptions)
      )
  Parser (Int -> Int -> Int -> Int -> TestnetOptions)
-> Parser Int -> Parser (Int -> Int -> Int -> TestnetOptions)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ReadM Int -> Mod OptionFields Int -> Parser Int
forall a. ReadM a -> Mod OptionFields a -> Parser a
OA.option ReadM Int
forall a. Read a => ReadM a
auto
      (   String -> Mod OptionFields Int
forall (f :: * -> *) a. HasName f => String -> Mod f a
OA.long String
"slot-duration"
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<>  String -> Mod OptionFields Int
forall (f :: * -> *) a. String -> Mod f a
OA.help String
"Slot duration"
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<>  String -> Mod OptionFields Int
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
OA.metavar String
"MILLISECONDS"
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<>  Mod OptionFields Int
forall a (f :: * -> *). Show a => Mod f a
OA.showDefault
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<>  Int -> Mod OptionFields Int
forall (f :: * -> *) a. HasValue f => a -> Mod f a
OA.value (TestnetOptions -> Int
slotDuration TestnetOptions
defaultTestnetOptions)
      )
  Parser (Int -> Int -> Int -> TestnetOptions)
-> Parser Int -> Parser (Int -> Int -> TestnetOptions)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ReadM Int -> Mod OptionFields Int -> Parser Int
forall a. ReadM a -> Mod OptionFields a -> Parser a
OA.option ReadM Int
forall a. Read a => ReadM a
auto
      (   String -> Mod OptionFields Int
forall (f :: * -> *) a. HasName f => String -> Mod f a
OA.long String
"security-param"
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<>  String -> Mod OptionFields Int
forall (f :: * -> *) a. String -> Mod f a
OA.help String
"Security parameter"
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<>  String -> Mod OptionFields Int
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
OA.metavar String
"INT"
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<>  Mod OptionFields Int
forall a (f :: * -> *). Show a => Mod f a
OA.showDefault
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<>  Int -> Mod OptionFields Int
forall (f :: * -> *) a. HasValue f => a -> Mod f a
OA.value (TestnetOptions -> Int
securityParam TestnetOptions
defaultTestnetOptions)
      )
  Parser (Int -> Int -> TestnetOptions)
-> Parser Int -> Parser (Int -> TestnetOptions)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ReadM Int -> Mod OptionFields Int -> Parser Int
forall a. ReadM a -> Mod OptionFields a -> Parser a
OA.option ReadM Int
forall a. Read a => ReadM a
auto
      (   String -> Mod OptionFields Int
forall (f :: * -> *) a. HasName f => String -> Mod f a
OA.long String
"n-poor-addresses"
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<>  String -> Mod OptionFields Int
forall (f :: * -> *) a. String -> Mod f a
OA.help String
"N poor addresses"
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<>  String -> Mod OptionFields Int
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
OA.metavar String
"INT"
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<>  Mod OptionFields Int
forall a (f :: * -> *). Show a => Mod f a
OA.showDefault
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<>  Int -> Mod OptionFields Int
forall (f :: * -> *) a. HasValue f => a -> Mod f a
OA.value (TestnetOptions -> Int
nPoorAddresses TestnetOptions
defaultTestnetOptions)
      )
  Parser (Int -> TestnetOptions)
-> Parser Int -> Parser TestnetOptions
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ReadM Int -> Mod OptionFields Int -> Parser Int
forall a. ReadM a -> Mod OptionFields a -> Parser a
OA.option ReadM Int
forall a. Read a => ReadM a
auto
      (   String -> Mod OptionFields Int
forall (f :: * -> *) a. HasName f => String -> Mod f a
OA.long String
"total-balance"
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<>  String -> Mod OptionFields Int
forall (f :: * -> *) a. String -> Mod f a
OA.help String
"Total Balance"
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<>  String -> Mod OptionFields Int
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
OA.metavar String
"INT"
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<>  Mod OptionFields Int
forall a (f :: * -> *). Show a => Mod f a
OA.showDefault
      Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<>  Int -> Mod OptionFields Int
forall (f :: * -> *) a. HasValue f => a -> Mod f a
OA.value (TestnetOptions -> Int
totalBalance TestnetOptions
defaultTestnetOptions)
      )

runColeOptions :: ColeOptions -> IO ()
runColeOptions :: ColeOptions -> IO ()
runColeOptions ColeOptions
opts = Maybe Int -> (Conf -> Integration [String]) -> IO ()
forall a. Maybe Int -> (Conf -> Integration a) -> IO ()
runTestnet (ColeOptions -> Maybe Int
maybeTestnetMagic ColeOptions
opts) (TestnetOptions -> Conf -> Integration [String]
Testnet.Cole.testnet (ColeOptions -> TestnetOptions
testnetOptions ColeOptions
opts))

cmdCole :: Mod CommandFields (IO ())
cmdCole :: Mod CommandFields (IO ())
cmdCole = String -> ParserInfo (IO ()) -> Mod CommandFields (IO ())
forall a. String -> ParserInfo a -> Mod CommandFields a
command String
"cole" (ParserInfo (IO ()) -> Mod CommandFields (IO ()))
-> ParserInfo (IO ()) -> Mod CommandFields (IO ())
forall a b. (a -> b) -> a -> b
$ (Parser (IO ()) -> InfoMod (IO ()) -> ParserInfo (IO ()))
-> InfoMod (IO ()) -> Parser (IO ()) -> ParserInfo (IO ())
forall a b c. (a -> b -> c) -> b -> a -> c
flip Parser (IO ()) -> InfoMod (IO ()) -> ParserInfo (IO ())
forall a. Parser a -> InfoMod a -> ParserInfo a
info InfoMod (IO ())
forall m. Monoid m => m
idm (Parser (IO ()) -> ParserInfo (IO ()))
-> Parser (IO ()) -> ParserInfo (IO ())
forall a b. (a -> b) -> a -> b
$ ColeOptions -> IO ()
runColeOptions (ColeOptions -> IO ()) -> Parser ColeOptions -> Parser (IO ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ColeOptions
optsCole