{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}

module Cardano.Api.Experimental.Tx.Internal.Certificate.Type
  ( Certificate (..)
  , AsType (AsCertificate)
  )
where

import Cardano.Api.HasTypeProxy
import Cardano.Api.Ledger qualified as L
import Cardano.Api.Serialise.Cbor
import Cardano.Api.Serialise.TextEnvelope.Internal

import Cardano.Binary qualified as CBOR

import Data.Typeable

data Certificate era where
  Certificate :: L.EraTxCert era => L.TxCert era -> Certificate era

deriving instance Show (Certificate era)

deriving instance Eq (Certificate era)

deriving instance Ord (Certificate era)

instance
  ( Typeable ledgerera
  , L.EraTxCert ledgerera
  )
  => HasTextEnvelope (Certificate ledgerera)
  where
  textEnvelopeType :: AsType (Certificate ledgerera) -> TextEnvelopeType
textEnvelopeType AsType (Certificate ledgerera)
_ = TextEnvelopeType
"Certificate"

instance Typeable era => HasTypeProxy (Certificate era) where
  data AsType (Certificate era) = AsCertificate
  proxyToAsType :: Proxy (Certificate era) -> AsType (Certificate era)
proxyToAsType Proxy (Certificate era)
_ = AsType (Certificate era)
forall era. AsType (Certificate era)
AsCertificate

instance
  ( Typeable ledgerera
  , L.EraTxCert ledgerera
  )
  => SerialiseAsCBOR (Certificate ledgerera)
  where
  serialiseToCBOR :: Certificate ledgerera -> ByteString
serialiseToCBOR (Certificate TxCert ledgerera
cert) =
    TxCert ledgerera -> ByteString
forall a. ToCBOR a => a -> ByteString
CBOR.serialize' TxCert ledgerera
cert
  deserialiseFromCBOR :: AsType (Certificate ledgerera)
-> ByteString -> Either DecoderError (Certificate ledgerera)
deserialiseFromCBOR AsType (Certificate ledgerera)
_ ByteString
bs =
    TxCert ledgerera -> Certificate ledgerera
forall era. EraTxCert era => TxCert era -> Certificate era
Certificate (TxCert ledgerera -> Certificate ledgerera)
-> Either DecoderError (TxCert ledgerera)
-> Either DecoderError (Certificate ledgerera)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ByteString -> Either DecoderError (TxCert ledgerera)
forall a. FromCBOR a => ByteString -> Either DecoderError a
CBOR.decodeFull' ByteString
bs