{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -Wno-orphans #-}

module Test.Cardano.Ledger.Shelley.Binary.RoundTrip (
  roundTripShelleyCommonSpec,
  roundTripStateEraTypesSpec,
) where

import Cardano.Ledger.Binary
import Cardano.Ledger.Compactible
import Cardano.Ledger.Core
import Cardano.Ledger.Shelley (ShelleyEra)
import Cardano.Ledger.Shelley.LedgerState
import Cardano.Ledger.Shelley.State
import Test.Cardano.Ledger.Common
import Test.Cardano.Ledger.Core.Binary.RoundTrip
import Test.Cardano.Ledger.Shelley.Arbitrary ()

roundTripShelleyCommonSpec ::
  forall era.
  ( EraTx era
  , EraGov era
  , EraStake era
  , Eq (StashedAVVMAddresses era)
  , Show (StashedAVVMAddresses era)
  , EncCBOR (StashedAVVMAddresses era)
  , DecCBOR (StashedAVVMAddresses era)
  , Arbitrary (StashedAVVMAddresses era)
  , Arbitrary (Tx era)
  , Arbitrary (TxBody era)
  , Arbitrary (TxOut era)
  , Arbitrary (TxCert era)
  , Arbitrary (TxWits era)
  , Arbitrary (TxAuxData era)
  , Arbitrary (Value era)
  , Arbitrary (CompactForm (Value era))
  , Arbitrary (Script era)
  , Arbitrary (GovState era)
  , Arbitrary (PParams era)
  , Arbitrary (PParamsUpdate era)
  , Arbitrary (InstantStake era)
  , RuleListEra era
  , EraCertState era
  , Arbitrary (CertState era)
  , DecCBOR (Script era)
  , DecCBOR (TxAuxData era)
  , DecCBOR (TxWits era)
  , DecCBOR (TxBody era)
  , DecCBOR (Tx era)
  ) =>
  Spec
roundTripShelleyCommonSpec :: forall era.
(EraTx era, EraGov era, EraStake era,
 Eq (StashedAVVMAddresses era), Show (StashedAVVMAddresses era),
 EncCBOR (StashedAVVMAddresses era),
 DecCBOR (StashedAVVMAddresses era),
 Arbitrary (StashedAVVMAddresses era), Arbitrary (Tx era),
 Arbitrary (TxBody era), Arbitrary (TxOut era),
 Arbitrary (TxCert era), Arbitrary (TxWits era),
 Arbitrary (TxAuxData era), Arbitrary (Value era),
 Arbitrary (CompactForm (Value era)), Arbitrary (Script era),
 Arbitrary (GovState era), Arbitrary (PParams era),
 Arbitrary (PParamsUpdate era), Arbitrary (InstantStake era),
 RuleListEra era, EraCertState era, Arbitrary (CertState era),
 DecCBOR (Script era), DecCBOR (TxAuxData era),
 DecCBOR (TxWits era), DecCBOR (TxBody era), DecCBOR (Tx era)) =>
Spec
roundTripShelleyCommonSpec = do
  forall era.
(EraTx era, EraCertState era, Arbitrary (Tx era),
 Arbitrary (TxBody era), Arbitrary (TxOut era),
 Arbitrary (TxCert era), Arbitrary (TxWits era),
 Arbitrary (TxAuxData era), Arbitrary (Value era),
 Arbitrary (CompactForm (Value era)), Arbitrary (Script era),
 Arbitrary (PParams era), Arbitrary (PParamsUpdate era),
 Arbitrary (CertState era), DecCBOR (Script era),
 DecCBOR (TxAuxData era), DecCBOR (TxWits era),
 DecCBOR (TxBody era), DecCBOR (Tx era), HasCallStack) =>
Spec
roundTripCoreEraTypesSpec @era
  forall era.
(EraTxOut era, EraGov era, EraStake era, EraCertState era,
 Eq (StashedAVVMAddresses era), Show (StashedAVVMAddresses era),
 EncCBOR (StashedAVVMAddresses era),
 DecCBOR (StashedAVVMAddresses era),
 Arbitrary (StashedAVVMAddresses era), Arbitrary (TxOut era),
 Arbitrary (Value era), Arbitrary (PParams era),
 Arbitrary (GovState era), Arbitrary (CertState era),
 Arbitrary (InstantStake era)) =>
Spec
roundTripStateEraTypesSpec @era
  forall era. (RuleListEra era, Era era, HasCallStack) => Spec
roundTripAllPredicateFailures @era

roundTripStateEraTypesSpec ::
  forall era.
  ( EraTxOut era
  , EraGov era
  , EraStake era
  , EraCertState era
  , Eq (StashedAVVMAddresses era)
  , Show (StashedAVVMAddresses era)
  , EncCBOR (StashedAVVMAddresses era)
  , DecCBOR (StashedAVVMAddresses era)
  , Arbitrary (StashedAVVMAddresses era)
  , Arbitrary (TxOut era)
  , Arbitrary (Value era)
  , Arbitrary (PParams era)
  , Arbitrary (GovState era)
  , Arbitrary (CertState era)
  , Arbitrary (InstantStake era)
  ) =>
  Spec
roundTripStateEraTypesSpec :: forall era.
(EraTxOut era, EraGov era, EraStake era, EraCertState era,
 Eq (StashedAVVMAddresses era), Show (StashedAVVMAddresses era),
 EncCBOR (StashedAVVMAddresses era),
 DecCBOR (StashedAVVMAddresses era),
 Arbitrary (StashedAVVMAddresses era), Arbitrary (TxOut era),
 Arbitrary (Value era), Arbitrary (PParams era),
 Arbitrary (GovState era), Arbitrary (CertState era),
 Arbitrary (InstantStake era)) =>
Spec
roundTripStateEraTypesSpec = do
  forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"State Types Families" forall a b. (a -> b) -> a -> b
$ do
    forall era t.
(Era era, Show t, Eq t, EncCBOR t, DecShareCBOR t, Arbitrary t,
 HasCallStack) =>
Spec
roundTripShareEraSpec @era @(GovState era)
  forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"State Types" forall a b. (a -> b) -> a -> b
$ do
    forall era (t :: * -> *).
(Era era, Show (t era), Eq (t era), EncCBOR (t era),
 DecShareCBOR (t era), Arbitrary (t era), HasCallStack) =>
Spec
roundTripShareEraTypeSpec @era @UTxOState
    forall era (t :: * -> *).
(Era era, Show (t era), Eq (t era), EncCBOR (t era),
 DecCBOR (t era), Arbitrary (t era), HasCallStack) =>
Spec
roundTripEraTypeSpec @era @EpochState
    forall era (t :: * -> *).
(Era era, Show (t era), Eq (t era), EncCBOR (t era),
 DecCBOR (t era), Arbitrary (t era), HasCallStack) =>
Spec
roundTripEraTypeSpec @era @NewEpochState

instance RuleListEra ShelleyEra where
  type
    EraRules ShelleyEra =
      '[ "DELEG"
       , "DELEGS"
       , "DELPL"
       , "LEDGER"
       , "LEDGERS"
       , "POOL"
       , "PPUP"
       , "UTXO"
       , "UTXOW"
       ]