module Testnet.Commands.Byron
  ( ByronOptions(..)
  , cmdByron
  , runByronOptions
  ) 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.Byron
import           Testnet.Run (runTestnet)
import           Text.Show

import qualified Options.Applicative as OA

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

optsByron :: Parser ByronOptions
optsByron :: Parser ByronOptions
optsByron = Maybe Int -> TestnetOptions -> ByronOptions
ByronOptions
  (Maybe Int -> TestnetOptions -> ByronOptions)
-> Parser (Maybe Int) -> Parser (TestnetOptions -> ByronOptions)
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 -> ByronOptions)
-> Parser TestnetOptions -> Parser ByronOptions
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)
      )

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

cmdByron :: Mod CommandFields (IO ())
cmdByron :: Mod CommandFields (IO ())
cmdByron = String -> ParserInfo (IO ()) -> Mod CommandFields (IO ())
forall a. String -> ParserInfo a -> Mod CommandFields a
command String
"byron" (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
$ ByronOptions -> IO ()
runByronOptions (ByronOptions -> IO ()) -> Parser ByronOptions -> Parser (IO ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByronOptions
optsByron