module Ouroboros.Consensus.Ledger.SupportsPeerSelection (
    LedgerSupportsPeerSelection (..)
  , PoolStake (..)
  , StakePoolRelay (..)
  , stakePoolRelayAccessPoint
    -- * Re-exports for convenience
  , DomainAccessPoint (..)
  , IP (..)
  , PortNumber
  , RelayAccessPoint (..)
  ) where

import           Control.DeepSeq (NFData (..))
import           Data.List.NonEmpty (NonEmpty)

import           Ouroboros.Network.PeerSelection.LedgerPeers
                     (DomainAccessPoint (..), IP (..), PoolStake (..),
                     PortNumber, RelayAccessPoint (..))

import           Ouroboros.Consensus.Ledger.Abstract (LedgerState)

-- | A relay registered for a stake pool
data StakePoolRelay =
    -- | One of the current relays
    CurrentRelay RelayAccessPoint

    -- | One of the future relays
  | FutureRelay  RelayAccessPoint
  deriving (Int -> StakePoolRelay -> ShowS
[StakePoolRelay] -> ShowS
StakePoolRelay -> String
(Int -> StakePoolRelay -> ShowS)
-> (StakePoolRelay -> String)
-> ([StakePoolRelay] -> ShowS)
-> Show StakePoolRelay
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [StakePoolRelay] -> ShowS
$cshowList :: [StakePoolRelay] -> ShowS
show :: StakePoolRelay -> String
$cshow :: StakePoolRelay -> String
showsPrec :: Int -> StakePoolRelay -> ShowS
$cshowsPrec :: Int -> StakePoolRelay -> ShowS
Show, StakePoolRelay -> StakePoolRelay -> Bool
(StakePoolRelay -> StakePoolRelay -> Bool)
-> (StakePoolRelay -> StakePoolRelay -> Bool) -> Eq StakePoolRelay
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: StakePoolRelay -> StakePoolRelay -> Bool
$c/= :: StakePoolRelay -> StakePoolRelay -> Bool
== :: StakePoolRelay -> StakePoolRelay -> Bool
$c== :: StakePoolRelay -> StakePoolRelay -> Bool
Eq)

instance NFData StakePoolRelay where
    rnf :: StakePoolRelay -> ()
rnf (CurrentRelay RelayAccessPoint
ra) = RelayAccessPoint -> ()
forall a. NFData a => a -> ()
rnf RelayAccessPoint
ra
    rnf (FutureRelay  RelayAccessPoint
ra) = RelayAccessPoint -> ()
forall a. NFData a => a -> ()
rnf RelayAccessPoint
ra

stakePoolRelayAccessPoint :: StakePoolRelay -> RelayAccessPoint
stakePoolRelayAccessPoint :: StakePoolRelay -> RelayAccessPoint
stakePoolRelayAccessPoint (CurrentRelay RelayAccessPoint
ra) = RelayAccessPoint
ra
stakePoolRelayAccessPoint (FutureRelay  RelayAccessPoint
ra) = RelayAccessPoint
ra

class LedgerSupportsPeerSelection blk where
  -- | Return peers registered in the ledger ordered by descending 'PoolStake'.
  --
  -- For example, for Shelley, the relays that have been registered in the
  -- ledger for the respective stake pools will be returned.
  --
  -- Ledgers/blocks that don't support staking can return an empty list.
  --
  -- Note: if the ledger state is old, the registered relays can also be old and
  -- may no longer be online.
  getPeers :: LedgerState blk -> [(PoolStake, NonEmpty StakePoolRelay)]