{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeApplications #-}

module Test.Cardano.Ledger.Allegra.Translation (
  allegraTranslationTests,
  allegraEncodeDecodeTests,
)
where

import Cardano.Ledger.Allegra (Allegra)
import Cardano.Ledger.Binary
import Cardano.Ledger.Core
import Cardano.Ledger.Genesis (NoGenesis (..))
import Cardano.Ledger.Shelley (Shelley)
import qualified Cardano.Ledger.Shelley.API as S
import Test.Cardano.Ledger.Binary.RoundTrip
import Test.Cardano.Ledger.Shelley.Generator.ShelleyEraGen ()
import Test.Cardano.Ledger.Shelley.Serialisation.Generators ()
import Test.Cardano.Ledger.TranslationTools (translateEraEncCBOR, translateEraEncoding)
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.HUnit (Assertion)
import Test.Tasty.QuickCheck (testProperty)

allegraEncodeDecodeTests :: TestTree
allegraEncodeDecodeTests :: TestTree
allegraEncodeDecodeTests =
  TestName -> [TestTree] -> TestTree
testGroup
    TestName
"encoded shelley types can be decoded as allegra types"
    [ forall a. Testable a => TestName -> a -> TestTree
testProperty
        TestName
"decoding auxiliary data"
        ( forall a b.
(ToCBOR a, DecCBOR (Annotator b), HasCallStack) =>
Version -> Version -> (b -> a -> Assertion) -> a -> Assertion
embedTripAnnExpectation @(TxAuxData Shelley) @(TxAuxData Allegra)
            (forall era. Era era => Version
eraProtVerLow @Shelley)
            (forall era. Era era => Version
eraProtVerLow @Allegra)
            (\TxAuxData Allegra
_ TxAuxData (ShelleyEra StandardCrypto)
_ -> forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
        )
    ]

allegraTranslationTests :: TestTree
allegraTranslationTests :: TestTree
allegraTranslationTests =
  TestName -> [TestTree] -> TestTree
testGroup
    TestName
"Allegra translation binary compatibiliby tests"
    [ forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"Tx compatibility" forall a b. (a -> b) -> a -> b
$
        forall era (f :: * -> *).
(HasCallStack, TranslateEra era f,
 Show (TranslationError era f)) =>
TranslationContext era
-> (f era -> Encoding)
-> (f (PreviousEra era) -> Encoding)
-> f (PreviousEra era)
-> Assertion
translateEraEncoding @Allegra @S.ShelleyTx forall era. NoGenesis era
NoGenesis forall a. ToCBOR a => a -> Encoding
toCBOR forall a. ToCBOR a => a -> Encoding
toCBOR
    , forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"ProposedPPUpdates compatibility" (forall (f :: * -> *).
(EncCBOR (f Allegra), EncCBOR (f (ShelleyEra StandardCrypto)),
 TranslateEra Allegra f, Show (TranslationError Allegra f)) =>
f (ShelleyEra StandardCrypto) -> Assertion
testTranslation @S.ProposedPPUpdates)
    , forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"ShelleyGovState compatibility" forall a b. (a -> b) -> a -> b
$
        forall era (f :: * -> *).
(HasCallStack, TranslateEra era f,
 Show (TranslationError era f)) =>
TranslationContext era
-> (f era -> Encoding)
-> (f (PreviousEra era) -> Encoding)
-> f (PreviousEra era)
-> Assertion
translateEraEncoding @Allegra @S.ShelleyGovState forall era. NoGenesis era
NoGenesis forall a. ToCBOR a => a -> Encoding
toCBOR forall a. ToCBOR a => a -> Encoding
toCBOR
    , forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"TxOut compatibility" (forall (f :: * -> *).
(EncCBOR (f Allegra), EncCBOR (f (ShelleyEra StandardCrypto)),
 TranslateEra Allegra f, Show (TranslationError Allegra f)) =>
f (ShelleyEra StandardCrypto) -> Assertion
testTranslation @S.ShelleyTxOut)
    , forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"UTxO compatibility" forall a b. (a -> b) -> a -> b
$
        forall era (f :: * -> *).
(HasCallStack, TranslateEra era f,
 Show (TranslationError era f)) =>
TranslationContext era
-> (f era -> Encoding)
-> (f (PreviousEra era) -> Encoding)
-> f (PreviousEra era)
-> Assertion
translateEraEncoding @Allegra @S.UTxO forall era. NoGenesis era
NoGenesis forall a. ToCBOR a => a -> Encoding
toCBOR forall a. ToCBOR a => a -> Encoding
toCBOR
    , forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"UTxOState compatibility" forall a b. (a -> b) -> a -> b
$
        forall era (f :: * -> *).
(HasCallStack, TranslateEra era f,
 Show (TranslationError era f)) =>
TranslationContext era
-> (f era -> Encoding)
-> (f (PreviousEra era) -> Encoding)
-> f (PreviousEra era)
-> Assertion
translateEraEncoding @Allegra @S.UTxOState forall era. NoGenesis era
NoGenesis forall a. ToCBOR a => a -> Encoding
toCBOR forall a. ToCBOR a => a -> Encoding
toCBOR
    , forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"LedgerState compatibility" forall a b. (a -> b) -> a -> b
$
        forall era (f :: * -> *).
(HasCallStack, TranslateEra era f,
 Show (TranslationError era f)) =>
TranslationContext era
-> (f era -> Encoding)
-> (f (PreviousEra era) -> Encoding)
-> f (PreviousEra era)
-> Assertion
translateEraEncoding @Allegra @S.LedgerState forall era. NoGenesis era
NoGenesis forall a. ToCBOR a => a -> Encoding
toCBOR forall a. ToCBOR a => a -> Encoding
toCBOR
    , forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"EpochState compatibility" forall a b. (a -> b) -> a -> b
$
        forall era (f :: * -> *).
(HasCallStack, TranslateEra era f,
 Show (TranslationError era f)) =>
TranslationContext era
-> (f era -> Encoding)
-> (f (PreviousEra era) -> Encoding)
-> f (PreviousEra era)
-> Assertion
translateEraEncoding @Allegra @S.EpochState forall era. NoGenesis era
NoGenesis forall a. ToCBOR a => a -> Encoding
toCBOR forall a. ToCBOR a => a -> Encoding
toCBOR
    , forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"ShelleyTxWits compatibility" forall a b. (a -> b) -> a -> b
$
        forall era (f :: * -> *).
(HasCallStack, TranslateEra era f,
 Show (TranslationError era f)) =>
TranslationContext era
-> (f era -> Encoding)
-> (f (PreviousEra era) -> Encoding)
-> f (PreviousEra era)
-> Assertion
translateEraEncoding @Allegra @S.ShelleyTxWits forall era. NoGenesis era
NoGenesis forall a. ToCBOR a => a -> Encoding
toCBOR forall a. ToCBOR a => a -> Encoding
toCBOR
    , forall a. Testable a => TestName -> a -> TestTree
testProperty TestName
"Update compatibility" (forall (f :: * -> *).
(EncCBOR (f Allegra), EncCBOR (f (ShelleyEra StandardCrypto)),
 TranslateEra Allegra f, Show (TranslationError Allegra f)) =>
f (ShelleyEra StandardCrypto) -> Assertion
testTranslation @S.Update)
    ]

testTranslation ::
  forall f.
  ( EncCBOR (f Allegra)
  , EncCBOR (f Shelley)
  , TranslateEra Allegra f
  , Show (TranslationError Allegra f)
  ) =>
  f Shelley ->
  Assertion
testTranslation :: forall (f :: * -> *).
(EncCBOR (f Allegra), EncCBOR (f (ShelleyEra StandardCrypto)),
 TranslateEra Allegra f, Show (TranslationError Allegra f)) =>
f (ShelleyEra StandardCrypto) -> Assertion
testTranslation = forall (proxy :: * -> *) era (f :: * -> *).
(HasCallStack, TranslateEra era f, EncCBOR (f era),
 EncCBOR (f (PreviousEra era)), Show (TranslationError era f)) =>
proxy era
-> TranslationContext era -> f (PreviousEra era) -> Assertion
translateEraEncCBOR ([] :: [Allegra]) forall era. NoGenesis era
NoGenesis