content: {-# LANGUAGE RecordWildCards #-}
  
  module Pos.Chain.Genesis.Initializer
         ( GenesisInitializer (..)
         , TestnetBalanceOptions (..)
         , FakeAvvmOptions (..)
         ) where
  
  import           Universum
  
  import           Data.Aeson.Options (defaultOptions)
  import           Data.Aeson.TH (deriveJSON)
  import           Fmt (genericF)
  import           Formatting (bprint, build, fixed, int, (%))
  import qualified Formatting.Buildable as Buildable
  
  import           Pos.Core.Common (CoinPortion)
  
  -- | This data type contains various options which determine genesis
  -- stakes, balanaces, heavy delegation, etc.
  data GenesisInitializer = GenesisInitializer
      { giTestBalance       :: !TestnetBalanceOptions
      , giFakeAvvmBalance   :: !FakeAvvmOptions
      , giAvvmBalanceFactor :: !CoinPortion
      -- ^ Avvm balances will be multiplied by this factor.
      , giUseHeavyDlg       :: !Bool
      -- ^ Whether to use heavyweight delegation for bootstrap era
      -- stakeholders.
      , giSeed              :: !Integer
        -- ^ Seed to use to generate secret data. There are two
        -- ways to use it:
        --
        -- 1. Keep it secret and use genesis data generated from it.
        -- 2. Just use it directly and keep it public if you want
        -- to deploy testing cluster.
      } deriving (Eq, Show)
  
  instance Buildable GenesisInitializer where
      build GenesisInitializer {..} = bprint
          ("GenesisInitializer {\n"%
              "  "%build%"\n"%
              "  "%build%"\n"%
              "  avvm balance factor: "%build%"\n"%
              "  heavyDlg: "%build%"\n"%
              "  seed: "%int%"\n"%
              "}\n"
          )
          giTestBalance
          giFakeAvvmBalance
          giAvvmBalanceFactor
          giUseHeavyDlg
          giSeed
  
  -- | These options determine balances of nodes specific for testnet.
  data TestnetBalanceOptions = TestnetBalanceOptions
      { tboPoors          :: !Word
      -- ^ Number of poor nodes (with small balance).
      , tboRichmen        :: !Word
      -- ^ Number of rich nodes (with huge balance).
      , tboTotalBalance   :: !Word64
      -- ^ Total balance owned by these nodes.
      , tboRichmenShare   :: !Double
      -- ^ Portion of stake owned by all richmen together.
      , tboUseHDAddresses :: !Bool
      -- ^ Whether generate plain addresses or with hd payload.
      } deriving (Eq, Show)
  
  instance Buildable TestnetBalanceOptions where
      build TestnetBalanceOptions {..} =
          bprint
              (int%" poor guys, "%
               int%" rich guys , "%
               "total balance is "%int%
               ", richmen share is "%fixed 3%
               " and useHDAddresses flag is " %build)
  
              tboPoors
              tboRichmen
              tboTotalBalance
              tboRichmenShare
              tboUseHDAddresses
  
  -- | These options determines balances of fake AVVM nodes which didn't
  -- really go through vending, but pretend they did.
  data FakeAvvmOptions = FakeAvvmOptions
      { faoCount      :: !Word
      , faoOneBalance :: !Word64
      } deriving (Eq, Show, Generic)
  
  instance Buildable FakeAvvmOptions where
      build = genericF
  
  deriveJSON defaultOptions ''GenesisInitializer
  deriveJSON defaultOptions ''TestnetBalanceOptions
  deriveJSON defaultOptions ''FakeAvvmOptions
  