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

module Test.Cardano.Ledger.Conway.Imp (
  spec,
  Babbage.alonzoToConwaySpec,
  conwayOnlySpec,
) where

import Cardano.Ledger.Conway (ConwayEra)
import Cardano.Ledger.Conway.Core
import Cardano.Ledger.Conway.Rules (
  ConwayEpochEvent,
  ConwayHardForkEvent,
  ConwayNewEpochEvent,
 )
import qualified Cardano.Ledger.Shelley.Rules as Shelley
import Control.State.Transition.Extended
import Data.Proxy
import qualified Test.Cardano.Ledger.Babbage.Imp as Babbage
import qualified Test.Cardano.Ledger.Conway.Imp.BbodySpec as BBODY
import qualified Test.Cardano.Ledger.Conway.Imp.CertsSpec as CERTS
import qualified Test.Cardano.Ledger.Conway.Imp.DelegSpec as DELEG
import qualified Test.Cardano.Ledger.Conway.Imp.EnactSpec as ENACT
import qualified Test.Cardano.Ledger.Conway.Imp.EpochSpec as EPOCH
import qualified Test.Cardano.Ledger.Conway.Imp.GovCertSpec as GOVCERT
import qualified Test.Cardano.Ledger.Conway.Imp.GovSpec as GOV
import qualified Test.Cardano.Ledger.Conway.Imp.HardForkSpec as HARDFORK
import qualified Test.Cardano.Ledger.Conway.Imp.LedgerSpec as LEDGER
import qualified Test.Cardano.Ledger.Conway.Imp.RatifySpec as RATIFY
import qualified Test.Cardano.Ledger.Conway.Imp.UtxoSpec as UTXO
import qualified Test.Cardano.Ledger.Conway.Imp.UtxosSpec as UTXOS
import qualified Test.Cardano.Ledger.Conway.Imp.UtxowSpec as UTXOW
import Test.Cardano.Ledger.Conway.ImpTest
import Test.Cardano.Ledger.Imp.Common

spec ::
  ( ConwayEraImp era
  , Event (EraRule "HARDFORK" era) ~ ConwayHardForkEvent era
  , Event (EraRule "EPOCH" era) ~ ConwayEpochEvent era
  , Event (EraRule "NEWEPOCH" era) ~ ConwayNewEpochEvent era
  , Event (EraRule "RUPD" era) ~ Shelley.RupdEvent
  ) =>
  proxy era ->
  Spec
spec :: forall era (proxy :: * -> *).
(ConwayEraImp era,
 Event (EraRule "HARDFORK" era) ~ ConwayHardForkEvent era,
 Event (EraRule "EPOCH" era) ~ ConwayEpochEvent era,
 Event (EraRule "NEWEPOCH" era) ~ ConwayNewEpochEvent era,
 Event (EraRule "RUPD" era) ~ RupdEvent) =>
proxy era -> Spec
spec proxy era
era = do
  proxy era -> Spec
forall era (proxy :: * -> *).
(BabbageEraImp era, Event (EraRule "RUPD" era) ~ RupdEvent) =>
proxy era -> Spec
Babbage.spec proxy era
era
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"ConwayEra Onwards" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ proxy era -> SpecWith (ImpInit (LedgerSpec era)) -> Spec
forall (proxy :: * -> *) era.
ShelleyEraImp era =>
proxy era -> SpecWith (ImpInit (LedgerSpec era)) -> Spec
withImpInitEachEraVersion proxy era
era (SpecWith (ImpInit (LedgerSpec era)) -> Spec)
-> SpecWith (ImpInit (LedgerSpec era)) -> Spec
forall a b. (a -> b) -> a -> b
$ do
    SpecWith (ImpInit (LedgerSpec era))
forall era. ConwayEraImp era => SpecWith (ImpInit (LedgerSpec era))
BBODY.spec
    SpecWith (ImpInit (LedgerSpec era))
forall era. ConwayEraImp era => SpecWith (ImpInit (LedgerSpec era))
DELEG.spec
    SpecWith (ImpInit (LedgerSpec era))
forall era.
(ConwayEraImp era,
 Event (EraRule "HARDFORK" era) ~ ConwayHardForkEvent era,
 Event (EraRule "EPOCH" era) ~ ConwayEpochEvent era,
 Event (EraRule "NEWEPOCH" era) ~ ConwayNewEpochEvent era) =>
SpecWith (ImpInit (LedgerSpec era))
ENACT.spec
    SpecWith (ImpInit (LedgerSpec era))
forall era.
(ConwayEraImp era,
 Event (EraRule "NEWEPOCH" era) ~ ConwayNewEpochEvent era,
 Event (EraRule "EPOCH" era) ~ ConwayEpochEvent era) =>
SpecWith (ImpInit (LedgerSpec era))
EPOCH.spec
    SpecWith (ImpInit (LedgerSpec era))
forall era. ConwayEraImp era => SpecWith (ImpInit (LedgerSpec era))
GOV.spec
    SpecWith (ImpInit (LedgerSpec era))
forall era. ConwayEraImp era => SpecWith (ImpInit (LedgerSpec era))
GOVCERT.spec
    SpecWith (ImpInit (LedgerSpec era))
forall era. ConwayEraImp era => SpecWith (ImpInit (LedgerSpec era))
LEDGER.spec
    SpecWith (ImpInit (LedgerSpec era))
forall era. ConwayEraImp era => SpecWith (ImpInit (LedgerSpec era))
HARDFORK.spec
    SpecWith (ImpInit (LedgerSpec era))
forall era.
(HasCallStack, ConwayEraImp era) =>
SpecWith (ImpInit (LedgerSpec era))
RATIFY.spec
    SpecWith (ImpInit (LedgerSpec era))
forall era. ConwayEraImp era => SpecWith (ImpInit (LedgerSpec era))
UTXO.spec
    SpecWith (ImpInit (LedgerSpec era))
forall era. ConwayEraImp era => SpecWith (ImpInit (LedgerSpec era))
UTXOS.spec
    SpecWith (ImpInit (LedgerSpec era))
forall era. ConwayEraImp era => SpecWith (ImpInit (LedgerSpec era))
UTXOW.spec

conwayOnlySpec :: Spec
conwayOnlySpec :: Spec
conwayOnlySpec = do
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"ConwayEra Specific" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ Proxy ConwayEra
-> SpecWith (ImpInit (LedgerSpec ConwayEra)) -> Spec
forall (proxy :: * -> *) era.
ShelleyEraImp era =>
proxy era -> SpecWith (ImpInit (LedgerSpec era)) -> Spec
withImpInitEachEraVersion (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @ConwayEra) (SpecWith (ImpInit (LedgerSpec ConwayEra)) -> Spec)
-> SpecWith (ImpInit (LedgerSpec ConwayEra)) -> Spec
forall a b. (a -> b) -> a -> b
$ do
    -- TODO: move to `spec` when ready: https://github.com/IntersectMBO/cardano-ledger/issues/5805
    SpecWith (ImpInit (LedgerSpec ConwayEra))
forall era. ConwayEraImp era => SpecWith (ImpInit (LedgerSpec era))
CERTS.spec
    SpecWith (ImpInit (LedgerSpec ConwayEra))
forall era.
(ConwayEraImp era, ShelleyEraTxCert era) =>
SpecWith (ImpInit (LedgerSpec era))
UTXO.conwayOnlySpec