{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

module Test.Cardano.Protocol.Binary.CddlSpec (spec) where

import Cardano.Ledger.Binary.Group (CBORGroup)
import Cardano.Ledger.Core
import Cardano.Ledger.Crypto
import Cardano.Ledger.Shelley
import Cardano.Protocol.TPraos.BHeader (BHBody, BHeader)
import Cardano.Protocol.TPraos.OCert (OCert)
import qualified Data.ByteString.Lazy as BSL
import Test.Cardano.Ledger.Binary.Cddl (
  beforeAllCddlFile,
  cddlRoundTripAnnCborSpec,
  cddlRoundTripCborSpec,
 )
import Test.Cardano.Ledger.Common
import Test.Cardano.Ledger.Shelley.Binary.Cddl (readShelleyCddlFiles)

spec :: Spec
spec :: Spec
spec =
  forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"CDDL" forall a b. (a -> b) -> a -> b
$ do
    let n :: Int
n = Int
3
    forall era. Era era => IO [ByteString] -> Int -> Spec
specForEra @Shelley IO [ByteString]
readShelleyCddlFiles Int
n

specForEra :: forall era. Era era => IO [BSL.ByteString] -> Int -> Spec
specForEra :: forall era. Era era => IO [ByteString] -> Int -> Spec
specForEra IO [ByteString]
readCddlFiles Int
n = do
  forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe (forall era. Era era => String
eraName @era) forall a b. (a -> b) -> a -> b
$
    HasCallStack => Int -> IO [ByteString] -> SpecWith CddlData -> Spec
beforeAllCddlFile Int
n IO [ByteString]
readCddlFiles forall a b. (a -> b) -> a -> b
$ do
      let v :: Version
v = forall era. Era era => Version
eraProtVerLow @era
      forall a.
(HasCallStack, Eq a, Show a, EncCBOR a, DecCBOR (Annotator a)) =>
Version -> Text -> SpecWith CddlData
cddlRoundTripAnnCborSpec @(BHeader StandardCrypto) Version
v Text
"header"
      forall a.
(HasCallStack, Eq a, Show a, EncCBOR a, DecCBOR a) =>
Version -> Text -> SpecWith CddlData
cddlRoundTripCborSpec @(BHBody StandardCrypto) Version
v Text
"header_body"
      forall a.
(HasCallStack, Eq a, Show a, EncCBOR a, DecCBOR a) =>
Version -> Text -> SpecWith CddlData
cddlRoundTripCborSpec @(CBORGroup (OCert StandardCrypto)) Version
v Text
"[ operational_cert ]"