{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE StandaloneDeriving #-}

module Cardano.Node.Protocol.Types
  ( Protocol(..)
  , SomeConsensusProtocol(..)
  ) where

import           Cardano.Prelude

import           Control.Monad.Fail (fail)
import           Data.Aeson
import           NoThunks.Class (NoThunks)

import qualified Cardano.Api.Protocol.Types as Cardano

import           Cardano.Node.Orphans ()
import           Cardano.Node.Queries (HasKESInfo, HasKESMetricsData)
import           Cardano.Tracing.Constraints (TraceConstraints)

data Protocol = ByronProtocol
              | ShelleyProtocol
              | CardanoProtocol
  deriving (Protocol -> Protocol -> Bool
(Protocol -> Protocol -> Bool)
-> (Protocol -> Protocol -> Bool) -> Eq Protocol
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Protocol -> Protocol -> Bool
$c/= :: Protocol -> Protocol -> Bool
== :: Protocol -> Protocol -> Bool
$c== :: Protocol -> Protocol -> Bool
Eq, Int -> Protocol -> ShowS
[Protocol] -> ShowS
Protocol -> String
(Int -> Protocol -> ShowS)
-> (Protocol -> String) -> ([Protocol] -> ShowS) -> Show Protocol
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Protocol] -> ShowS
$cshowList :: [Protocol] -> ShowS
show :: Protocol -> String
$cshow :: Protocol -> String
showsPrec :: Int -> Protocol -> ShowS
$cshowsPrec :: Int -> Protocol -> ShowS
Show, (forall x. Protocol -> Rep Protocol x)
-> (forall x. Rep Protocol x -> Protocol) -> Generic Protocol
forall x. Rep Protocol x -> Protocol
forall x. Protocol -> Rep Protocol x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Protocol x -> Protocol
$cfrom :: forall x. Protocol -> Rep Protocol x
Generic)

deriving instance NFData Protocol
deriving instance NoThunks Protocol

instance FromJSON Protocol where
  parseJSON :: Value -> Parser Protocol
parseJSON =
    String -> (Text -> Parser Protocol) -> Value -> Parser Protocol
forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"Protocol" ((Text -> Parser Protocol) -> Value -> Parser Protocol)
-> (Text -> Parser Protocol) -> Value -> Parser Protocol
forall a b. (a -> b) -> a -> b
$ \Text
str -> case Text
str of

      -- The new names
      Text
"Byron" -> Protocol -> Parser Protocol
forall (f :: * -> *) a. Applicative f => a -> f a
pure Protocol
ByronProtocol
      Text
"Shelley" -> Protocol -> Parser Protocol
forall (f :: * -> *) a. Applicative f => a -> f a
pure Protocol
ShelleyProtocol
      Text
"Cardano" -> Protocol -> Parser Protocol
forall (f :: * -> *) a. Applicative f => a -> f a
pure Protocol
CardanoProtocol

      -- The old names
      Text
"RealPBFT" -> Protocol -> Parser Protocol
forall (f :: * -> *) a. Applicative f => a -> f a
pure Protocol
ByronProtocol
      Text
"TPraos" -> Protocol -> Parser Protocol
forall (f :: * -> *) a. Applicative f => a -> f a
pure Protocol
ShelleyProtocol

      Text
_ -> String -> Parser Protocol
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser Protocol) -> String -> Parser Protocol
forall a b. (a -> b) -> a -> b
$ String
"Parsing of Protocol failed. "
                String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Text -> String
forall a b. (Show a, ConvertText String b) => a -> b
show Text
str String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" is not a valid protocol"



data SomeConsensusProtocol where

     SomeConsensusProtocol :: forall blk. ( Cardano.Protocol IO blk
                                          , HasKESMetricsData blk
                                          , HasKESInfo blk
                                          , TraceConstraints blk
                                          )
                           => Cardano.BlockType blk
                           -> Cardano.ProtocolInfoArgs IO blk
                           -> SomeConsensusProtocol