module Tendermint.SDK.Modules.Validators.Query
  (
    querier
  , QueryApi
  )where

import qualified Data.Map.Strict                          as Map
import qualified Data.Set                                 as Set
import           Data.Word                                (Word64)
import           Polysemy                                 (Members, Sem)
import           Servant.API
import           Tendermint.SDK.BaseApp
import qualified Tendermint.SDK.BaseApp.Store.Map         as M
import qualified Tendermint.SDK.BaseApp.Store.Var         as V
import qualified Tendermint.SDK.Modules.Validators.Keeper as Keeper
import           Tendermint.SDK.Modules.Validators.Store
import           Tendermint.SDK.Modules.Validators.Types

type QueryApi = GetPowerOf :<|> GetValidatorsKeys :<|> GetValidators

querier
  :: Members QueryEffs r
  => Members Keeper.ValidatorsEffs r
  => RouteQ QueryApi r
querier :: RouteQ QueryApi r
querier =
  QueryArgs PubKey_ -> Sem r (QueryResult Word64)
forall (r :: [(* -> *) -> * -> *]).
Members QueryEffs r =>
RouteQ GetPowerOf r
getPowerOfQuery (QueryArgs PubKey_ -> Sem r (QueryResult Word64))
-> ((QueryArgs () -> Sem r (QueryResult KeySet))
    :<|> Sem r (QueryResult (Map PubKey_ Word64)))
-> (QueryArgs PubKey_ -> Sem r (QueryResult Word64))
   :<|> ((QueryArgs () -> Sem r (QueryResult KeySet))
         :<|> Sem r (QueryResult (Map PubKey_ Word64)))
forall a b. a -> b -> a :<|> b
:<|> QueryArgs () -> Sem r (QueryResult KeySet)
forall (r :: [(* -> *) -> * -> *]).
Members QueryEffs r =>
RouteQ GetValidatorsKeys r
getValidatorsKeys (QueryArgs () -> Sem r (QueryResult KeySet))
-> Sem r (QueryResult (Map PubKey_ Word64))
-> (QueryArgs () -> Sem r (QueryResult KeySet))
   :<|> Sem r (QueryResult (Map PubKey_ Word64))
forall a b. a -> b -> a :<|> b
:<|> Sem r (QueryResult (Map PubKey_ Word64))
forall (r :: [(* -> *) -> * -> *]).
Members ValidatorsEffs r =>
Sem r (QueryResult (Map PubKey_ Word64))
getValidators

type GetPowerOf = "powerOf" :> StoreLeaf (M.Map PubKey_ Word64)
getPowerOfQuery
  :: Members QueryEffs r
  => RouteQ GetPowerOf r
getPowerOfQuery :: RouteQ GetPowerOf r
getPowerOfQuery = Map PubKey_ Word64
-> QueryArgs PubKey_ -> Sem r (QueryResult Word64)
forall ns h. StoreQueryHandler ns h => ns -> h
storeQueryHandler Map PubKey_ Word64
validatorsMap

type GetValidatorsKeys = "validatorsKeys" :> StoreLeaf (V.Var KeySet)
getValidatorsKeys
  :: Members QueryEffs r
  => RouteQ GetValidatorsKeys r
getValidatorsKeys :: RouteQ GetValidatorsKeys r
getValidatorsKeys = Var KeySet -> QueryArgs () -> Sem r (QueryResult KeySet)
forall ns h. StoreQueryHandler ns h => ns -> h
storeQueryHandler Var KeySet
validatorsKeySet

type GetValidators = "validators" :> Leaf (Map.Map PubKey_ Word64)
getValidators
  :: Members Keeper.ValidatorsEffs r
  => Sem r (QueryResult (Map.Map PubKey_ Word64))
getValidators :: Sem r (QueryResult (Map PubKey_ Word64))
getValidators = do
  [PubKey_]
keyList <- (Set PubKey_ -> [PubKey_])
-> Sem r (Set PubKey_) -> Sem r [PubKey_]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Set PubKey_ -> [PubKey_]
forall a. Set a -> [a]
Set.toList Sem r (Set PubKey_)
forall (r :: [(* -> *) -> * -> *]).
MemberWithError ValidatorsKeeper r =>
Sem r (Set PubKey_)
Keeper.getValidatorsKeys
  Map PubKey_ Word64
vs <- ([(PubKey_, Word64)] -> Map PubKey_ Word64)
-> Sem r [(PubKey_, Word64)] -> Sem r (Map PubKey_ Word64)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(PubKey_, Word64)] -> Map PubKey_ Word64
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList (Sem r [(PubKey_, Word64)] -> Sem r (Map PubKey_ Word64))
-> Sem r [(PubKey_, Word64)] -> Sem r (Map PubKey_ Word64)
forall a b. (a -> b) -> a -> b
$ (PubKey_ -> Sem r (PubKey_, Word64))
-> [PubKey_] -> Sem r [(PubKey_, Word64)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\k :: PubKey_
k -> (Word64 -> (PubKey_, Word64))
-> Sem r Word64 -> Sem r (PubKey_, Word64)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\p :: Word64
p -> (PubKey_
k, Word64
p)) (PubKey_ -> Sem r Word64
forall (r :: [(* -> *) -> * -> *]).
MemberWithError ValidatorsKeeper r =>
PubKey_ -> Sem r Word64
Keeper.getPowerOf PubKey_
k)) [PubKey_]
keyList
  QueryResult (Map PubKey_ Word64)
-> Sem r (QueryResult (Map PubKey_ Word64))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (QueryResult (Map PubKey_ Word64)
 -> Sem r (QueryResult (Map PubKey_ Word64)))
-> QueryResult (Map PubKey_ Word64)
-> Sem r (QueryResult (Map PubKey_ Word64))
forall a b. (a -> b) -> a -> b
$ QueryResult :: forall a.
a -> Int64 -> Base64String -> Maybe Proof -> Int64 -> QueryResult a
QueryResult
    { queryResultData :: Map PubKey_ Word64
queryResultData = Map PubKey_ Word64
vs
    , queryResultIndex :: Int64
queryResultIndex = 0
    , queryResultKey :: Base64String
queryResultKey = ""
    , queryResultProof :: Maybe Proof
queryResultProof = Maybe Proof
forall a. Maybe a
Nothing
    , queryResultHeight :: Int64
queryResultHeight = 0
    }