{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RankNTypes #-}

module Cardano.Api.Eras.Case
  ( -- Case on CardanoEra
    caseByronOrShelleyBasedEra
  , caseByronToAlonzoOrBabbageEraOnwards
  -- Case on ShelleyBasedEra
  , caseShelleyEraOnlyOrAllegraEraOnwards
  , caseShelleyToAllegraOrMaryEraOnwards
  , caseShelleyToMaryOrAlonzoEraOnwards
  , caseShelleyToAlonzoOrBabbageEraOnwards
  , caseShelleyToBabbageOrConwayEraOnwards
  -- Conversions
  , shelleyToAlonzoEraToShelleyToBabbageEra
  , alonzoEraOnwardsToMaryEraOnwards
  , babbageEraOnwardsToMaryEraOnwards
  , babbageEraOnwardsToAlonzoEraOnwards
  )
where

import           Cardano.Api.Eon.AllegraEraOnwards
import           Cardano.Api.Eon.AlonzoEraOnwards
import           Cardano.Api.Eon.BabbageEraOnwards
import           Cardano.Api.Eon.ByronToAlonzoEra
import           Cardano.Api.Eon.ConwayEraOnwards
import           Cardano.Api.Eon.MaryEraOnwards
import           Cardano.Api.Eon.ShelleyBasedEra
import           Cardano.Api.Eon.ShelleyEraOnly
import           Cardano.Api.Eon.ShelleyToAllegraEra
import           Cardano.Api.Eon.ShelleyToAlonzoEra
import           Cardano.Api.Eon.ShelleyToBabbageEra
import           Cardano.Api.Eon.ShelleyToMaryEra
import           Cardano.Api.Eras.Core

-- | @caseByronOrShelleyBasedEra f g era@ returns @f@ in Byron and applies @g@ to Shelley-based eras.
caseByronOrShelleyBasedEra
  :: ()
  => a
  -> (ShelleyBasedEraConstraints era => ShelleyBasedEra era -> a)
  -> CardanoEra era
  -> a
caseByronOrShelleyBasedEra :: forall a era.
a
-> (ShelleyBasedEraConstraints era => ShelleyBasedEra era -> a)
-> CardanoEra era
-> a
caseByronOrShelleyBasedEra a
l ShelleyBasedEraConstraints era => ShelleyBasedEra era -> a
r = \case
  CardanoEra era
ByronEra -> a
l -- We no longer provide the witness because Byron is isolated.
  -- This function will be deleted shortly after build-raw --byron-era is
  -- deprecated in cardano-cli
  CardanoEra era
ShelleyEra -> ShelleyBasedEraConstraints era => ShelleyBasedEra era -> a
ShelleyBasedEra era -> a
r ShelleyBasedEra era
ShelleyBasedEra ShelleyEra
ShelleyBasedEraShelley
  CardanoEra era
AllegraEra -> ShelleyBasedEraConstraints era => ShelleyBasedEra era -> a
ShelleyBasedEra era -> a
r ShelleyBasedEra era
ShelleyBasedEra AllegraEra
ShelleyBasedEraAllegra
  CardanoEra era
MaryEra -> ShelleyBasedEraConstraints era => ShelleyBasedEra era -> a
ShelleyBasedEra era -> a
r ShelleyBasedEra era
ShelleyBasedEra MaryEra
ShelleyBasedEraMary
  CardanoEra era
AlonzoEra -> ShelleyBasedEraConstraints era => ShelleyBasedEra era -> a
ShelleyBasedEra era -> a
r ShelleyBasedEra era
ShelleyBasedEra AlonzoEra
ShelleyBasedEraAlonzo
  CardanoEra era
BabbageEra -> ShelleyBasedEraConstraints era => ShelleyBasedEra era -> a
ShelleyBasedEra era -> a
r ShelleyBasedEra era
ShelleyBasedEra BabbageEra
ShelleyBasedEraBabbage
  CardanoEra era
ConwayEra -> ShelleyBasedEraConstraints era => ShelleyBasedEra era -> a
ShelleyBasedEra era -> a
r ShelleyBasedEra era
ShelleyBasedEra ConwayEra
ShelleyBasedEraConway

-- | @caseByronToAlonzoOrBabbageEraOnwards f g era@ applies @f@ to byron, shelley, allegra, mary, and alonzo;
-- and @g@ to babbage and later eras.
caseByronToAlonzoOrBabbageEraOnwards
  :: ()
  => (ByronToAlonzoEraConstraints era => ByronToAlonzoEra era -> a)
  -> (BabbageEraOnwardsConstraints era => BabbageEraOnwards era -> a)
  -> CardanoEra era
  -> a
caseByronToAlonzoOrBabbageEraOnwards :: forall era a.
(ByronToAlonzoEraConstraints era => ByronToAlonzoEra era -> a)
-> (BabbageEraOnwardsConstraints era => BabbageEraOnwards era -> a)
-> CardanoEra era
-> a
caseByronToAlonzoOrBabbageEraOnwards ByronToAlonzoEraConstraints era => ByronToAlonzoEra era -> a
l BabbageEraOnwardsConstraints era => BabbageEraOnwards era -> a
r = \case
  CardanoEra era
ByronEra -> ByronToAlonzoEraConstraints era => ByronToAlonzoEra era -> a
ByronToAlonzoEra era -> a
l ByronToAlonzoEra era
ByronToAlonzoEra ByronEra
ByronToAlonzoEraByron
  CardanoEra era
ShelleyEra -> ByronToAlonzoEraConstraints era => ByronToAlonzoEra era -> a
ByronToAlonzoEra era -> a
l ByronToAlonzoEra era
ByronToAlonzoEra ShelleyEra
ByronToAlonzoEraShelley
  CardanoEra era
AllegraEra -> ByronToAlonzoEraConstraints era => ByronToAlonzoEra era -> a
ByronToAlonzoEra era -> a
l ByronToAlonzoEra era
ByronToAlonzoEra AllegraEra
ByronToAlonzoEraAllegra
  CardanoEra era
MaryEra -> ByronToAlonzoEraConstraints era => ByronToAlonzoEra era -> a
ByronToAlonzoEra era -> a
l ByronToAlonzoEra era
ByronToAlonzoEra MaryEra
ByronToAlonzoEraMary
  CardanoEra era
AlonzoEra -> ByronToAlonzoEraConstraints era => ByronToAlonzoEra era -> a
ByronToAlonzoEra era -> a
l ByronToAlonzoEra era
ByronToAlonzoEra AlonzoEra
ByronToAlonzoEraAlonzo
  CardanoEra era
BabbageEra -> BabbageEraOnwardsConstraints era => BabbageEraOnwards era -> a
BabbageEraOnwards era -> a
r BabbageEraOnwards era
BabbageEraOnwards BabbageEra
BabbageEraOnwardsBabbage
  CardanoEra era
ConwayEra -> BabbageEraOnwardsConstraints era => BabbageEraOnwards era -> a
BabbageEraOnwards era -> a
r BabbageEraOnwards era
BabbageEraOnwards ConwayEra
BabbageEraOnwardsConway

-- | @caseShelleyEraOnlyOrAllegraEraOnwards f g era@ applies @f@ to shelley;
-- and applies @g@ to allegra and later eras.
caseShelleyEraOnlyOrAllegraEraOnwards
  :: ()
  => (ShelleyEraOnlyConstraints era => ShelleyEraOnly era -> a)
  -> (AllegraEraOnwardsConstraints era => AllegraEraOnwards era -> a)
  -> ShelleyBasedEra era
  -> a
caseShelleyEraOnlyOrAllegraEraOnwards :: forall era a.
(ShelleyEraOnlyConstraints era => ShelleyEraOnly era -> a)
-> (AllegraEraOnwardsConstraints era => AllegraEraOnwards era -> a)
-> ShelleyBasedEra era
-> a
caseShelleyEraOnlyOrAllegraEraOnwards ShelleyEraOnlyConstraints era => ShelleyEraOnly era -> a
l AllegraEraOnwardsConstraints era => AllegraEraOnwards era -> a
r = \case
  ShelleyBasedEra era
ShelleyBasedEraShelley -> ShelleyEraOnlyConstraints era => ShelleyEraOnly era -> a
ShelleyEraOnly era -> a
l ShelleyEraOnly era
ShelleyEraOnly ShelleyEra
ShelleyEraOnlyShelley
  ShelleyBasedEra era
ShelleyBasedEraAllegra -> AllegraEraOnwardsConstraints era => AllegraEraOnwards era -> a
AllegraEraOnwards era -> a
r AllegraEraOnwards era
AllegraEraOnwards AllegraEra
AllegraEraOnwardsAllegra
  ShelleyBasedEra era
ShelleyBasedEraMary -> AllegraEraOnwardsConstraints era => AllegraEraOnwards era -> a
AllegraEraOnwards era -> a
r AllegraEraOnwards era
AllegraEraOnwards MaryEra
AllegraEraOnwardsMary
  ShelleyBasedEra era
ShelleyBasedEraAlonzo -> AllegraEraOnwardsConstraints era => AllegraEraOnwards era -> a
AllegraEraOnwards era -> a
r AllegraEraOnwards era
AllegraEraOnwards AlonzoEra
AllegraEraOnwardsAlonzo
  ShelleyBasedEra era
ShelleyBasedEraBabbage -> AllegraEraOnwardsConstraints era => AllegraEraOnwards era -> a
AllegraEraOnwards era -> a
r AllegraEraOnwards era
AllegraEraOnwards BabbageEra
AllegraEraOnwardsBabbage
  ShelleyBasedEra era
ShelleyBasedEraConway -> AllegraEraOnwardsConstraints era => AllegraEraOnwards era -> a
AllegraEraOnwards era -> a
r AllegraEraOnwards era
AllegraEraOnwards ConwayEra
AllegraEraOnwardsConway

-- | @caseShelleyToAllegraOrMaryEraOnwards f g era@ applies @f@ to shelley and allegra;
-- and applies @g@ to mary and later eras.
caseShelleyToAllegraOrMaryEraOnwards
  :: ()
  => (ShelleyToAllegraEraConstraints era => ShelleyToAllegraEra era -> a)
  -> (MaryEraOnwardsConstraints era => MaryEraOnwards era -> a)
  -> ShelleyBasedEra era
  -> a
caseShelleyToAllegraOrMaryEraOnwards :: forall era a.
(ShelleyToAllegraEraConstraints era =>
 ShelleyToAllegraEra era -> a)
-> (MaryEraOnwardsConstraints era => MaryEraOnwards era -> a)
-> ShelleyBasedEra era
-> a
caseShelleyToAllegraOrMaryEraOnwards ShelleyToAllegraEraConstraints era => ShelleyToAllegraEra era -> a
l MaryEraOnwardsConstraints era => MaryEraOnwards era -> a
r = \case
  ShelleyBasedEra era
ShelleyBasedEraShelley -> ShelleyToAllegraEraConstraints era => ShelleyToAllegraEra era -> a
ShelleyToAllegraEra era -> a
l ShelleyToAllegraEra era
ShelleyToAllegraEra ShelleyEra
ShelleyToAllegraEraShelley
  ShelleyBasedEra era
ShelleyBasedEraAllegra -> ShelleyToAllegraEraConstraints era => ShelleyToAllegraEra era -> a
ShelleyToAllegraEra era -> a
l ShelleyToAllegraEra era
ShelleyToAllegraEra AllegraEra
ShelleyToAllegraEraAllegra
  ShelleyBasedEra era
ShelleyBasedEraMary -> MaryEraOnwardsConstraints era => MaryEraOnwards era -> a
MaryEraOnwards era -> a
r MaryEraOnwards era
MaryEraOnwards MaryEra
MaryEraOnwardsMary
  ShelleyBasedEra era
ShelleyBasedEraAlonzo -> MaryEraOnwardsConstraints era => MaryEraOnwards era -> a
MaryEraOnwards era -> a
r MaryEraOnwards era
MaryEraOnwards AlonzoEra
MaryEraOnwardsAlonzo
  ShelleyBasedEra era
ShelleyBasedEraBabbage -> MaryEraOnwardsConstraints era => MaryEraOnwards era -> a
MaryEraOnwards era -> a
r MaryEraOnwards era
MaryEraOnwards BabbageEra
MaryEraOnwardsBabbage
  ShelleyBasedEra era
ShelleyBasedEraConway -> MaryEraOnwardsConstraints era => MaryEraOnwards era -> a
MaryEraOnwards era -> a
r MaryEraOnwards era
MaryEraOnwards ConwayEra
MaryEraOnwardsConway

-- | @caseShelleyToMaryOrAlonzoEraOnwards f g era@ applies @f@ to shelley, allegra, and mary;
-- and applies @g@ to alonzo and later eras.
caseShelleyToMaryOrAlonzoEraOnwards
  :: ()
  => (ShelleyToMaryEraConstraints era => ShelleyToMaryEra era -> a)
  -> (AlonzoEraOnwardsConstraints era => AlonzoEraOnwards era -> a)
  -> ShelleyBasedEra era
  -> a
caseShelleyToMaryOrAlonzoEraOnwards :: forall era a.
(ShelleyToMaryEraConstraints era => ShelleyToMaryEra era -> a)
-> (AlonzoEraOnwardsConstraints era => AlonzoEraOnwards era -> a)
-> ShelleyBasedEra era
-> a
caseShelleyToMaryOrAlonzoEraOnwards ShelleyToMaryEraConstraints era => ShelleyToMaryEra era -> a
l AlonzoEraOnwardsConstraints era => AlonzoEraOnwards era -> a
r = \case
  ShelleyBasedEra era
ShelleyBasedEraShelley -> ShelleyToMaryEraConstraints era => ShelleyToMaryEra era -> a
ShelleyToMaryEra era -> a
l ShelleyToMaryEra era
ShelleyToMaryEra ShelleyEra
ShelleyToMaryEraShelley
  ShelleyBasedEra era
ShelleyBasedEraAllegra -> ShelleyToMaryEraConstraints era => ShelleyToMaryEra era -> a
ShelleyToMaryEra era -> a
l ShelleyToMaryEra era
ShelleyToMaryEra AllegraEra
ShelleyToMaryEraAllegra
  ShelleyBasedEra era
ShelleyBasedEraMary -> ShelleyToMaryEraConstraints era => ShelleyToMaryEra era -> a
ShelleyToMaryEra era -> a
l ShelleyToMaryEra era
ShelleyToMaryEra MaryEra
ShelleyToMaryEraMary
  ShelleyBasedEra era
ShelleyBasedEraAlonzo -> AlonzoEraOnwardsConstraints era => AlonzoEraOnwards era -> a
AlonzoEraOnwards era -> a
r AlonzoEraOnwards era
AlonzoEraOnwards AlonzoEra
AlonzoEraOnwardsAlonzo
  ShelleyBasedEra era
ShelleyBasedEraBabbage -> AlonzoEraOnwardsConstraints era => AlonzoEraOnwards era -> a
AlonzoEraOnwards era -> a
r AlonzoEraOnwards era
AlonzoEraOnwards BabbageEra
AlonzoEraOnwardsBabbage
  ShelleyBasedEra era
ShelleyBasedEraConway -> AlonzoEraOnwardsConstraints era => AlonzoEraOnwards era -> a
AlonzoEraOnwards era -> a
r AlonzoEraOnwards era
AlonzoEraOnwards ConwayEra
AlonzoEraOnwardsConway

-- | @caseShelleyToAlonzoOrBabbageEraOnwards f g era@ applies @f@ to shelley, allegra, mary, and alonzo;
-- and applies @g@ to babbage and later eras.
caseShelleyToAlonzoOrBabbageEraOnwards
  :: ()
  => (ShelleyToAlonzoEraConstraints era => ShelleyToAlonzoEra era -> a)
  -> (BabbageEraOnwardsConstraints era => BabbageEraOnwards era -> a)
  -> ShelleyBasedEra era
  -> a
caseShelleyToAlonzoOrBabbageEraOnwards :: forall era a.
(ShelleyToAlonzoEraConstraints era => ShelleyToAlonzoEra era -> a)
-> (BabbageEraOnwardsConstraints era => BabbageEraOnwards era -> a)
-> ShelleyBasedEra era
-> a
caseShelleyToAlonzoOrBabbageEraOnwards ShelleyToAlonzoEraConstraints era => ShelleyToAlonzoEra era -> a
l BabbageEraOnwardsConstraints era => BabbageEraOnwards era -> a
r = \case
  ShelleyBasedEra era
ShelleyBasedEraShelley -> ShelleyToAlonzoEraConstraints era => ShelleyToAlonzoEra era -> a
ShelleyToAlonzoEra era -> a
l ShelleyToAlonzoEra era
ShelleyToAlonzoEra ShelleyEra
ShelleyToAlonzoEraShelley
  ShelleyBasedEra era
ShelleyBasedEraAllegra -> ShelleyToAlonzoEraConstraints era => ShelleyToAlonzoEra era -> a
ShelleyToAlonzoEra era -> a
l ShelleyToAlonzoEra era
ShelleyToAlonzoEra AllegraEra
ShelleyToAlonzoEraAllegra
  ShelleyBasedEra era
ShelleyBasedEraMary -> ShelleyToAlonzoEraConstraints era => ShelleyToAlonzoEra era -> a
ShelleyToAlonzoEra era -> a
l ShelleyToAlonzoEra era
ShelleyToAlonzoEra MaryEra
ShelleyToAlonzoEraMary
  ShelleyBasedEra era
ShelleyBasedEraAlonzo -> ShelleyToAlonzoEraConstraints era => ShelleyToAlonzoEra era -> a
ShelleyToAlonzoEra era -> a
l ShelleyToAlonzoEra era
ShelleyToAlonzoEra AlonzoEra
ShelleyToAlonzoEraAlonzo
  ShelleyBasedEra era
ShelleyBasedEraBabbage -> BabbageEraOnwardsConstraints era => BabbageEraOnwards era -> a
BabbageEraOnwards era -> a
r BabbageEraOnwards era
BabbageEraOnwards BabbageEra
BabbageEraOnwardsBabbage
  ShelleyBasedEra era
ShelleyBasedEraConway -> BabbageEraOnwardsConstraints era => BabbageEraOnwards era -> a
BabbageEraOnwards era -> a
r BabbageEraOnwards era
BabbageEraOnwards ConwayEra
BabbageEraOnwardsConway

-- | @caseShelleyToBabbageOrConwayEraOnwards f g era@ applies @f@ to eras before conway;
-- and applies @g@ to conway and later eras.
caseShelleyToBabbageOrConwayEraOnwards
  :: ()
  => (ShelleyToBabbageEraConstraints era => ShelleyToBabbageEra era -> a)
  -> (ConwayEraOnwardsConstraints era => ConwayEraOnwards era -> a)
  -> ShelleyBasedEra era
  -> a
caseShelleyToBabbageOrConwayEraOnwards :: forall era a.
(ShelleyToBabbageEraConstraints era =>
 ShelleyToBabbageEra era -> a)
-> (ConwayEraOnwardsConstraints era => ConwayEraOnwards era -> a)
-> ShelleyBasedEra era
-> a
caseShelleyToBabbageOrConwayEraOnwards ShelleyToBabbageEraConstraints era => ShelleyToBabbageEra era -> a
l ConwayEraOnwardsConstraints era => ConwayEraOnwards era -> a
r = \case
  ShelleyBasedEra era
ShelleyBasedEraShelley -> ShelleyToBabbageEraConstraints era => ShelleyToBabbageEra era -> a
ShelleyToBabbageEra era -> a
l ShelleyToBabbageEra era
ShelleyToBabbageEra ShelleyEra
ShelleyToBabbageEraShelley
  ShelleyBasedEra era
ShelleyBasedEraAllegra -> ShelleyToBabbageEraConstraints era => ShelleyToBabbageEra era -> a
ShelleyToBabbageEra era -> a
l ShelleyToBabbageEra era
ShelleyToBabbageEra AllegraEra
ShelleyToBabbageEraAllegra
  ShelleyBasedEra era
ShelleyBasedEraMary -> ShelleyToBabbageEraConstraints era => ShelleyToBabbageEra era -> a
ShelleyToBabbageEra era -> a
l ShelleyToBabbageEra era
ShelleyToBabbageEra MaryEra
ShelleyToBabbageEraMary
  ShelleyBasedEra era
ShelleyBasedEraAlonzo -> ShelleyToBabbageEraConstraints era => ShelleyToBabbageEra era -> a
ShelleyToBabbageEra era -> a
l ShelleyToBabbageEra era
ShelleyToBabbageEra AlonzoEra
ShelleyToBabbageEraAlonzo
  ShelleyBasedEra era
ShelleyBasedEraBabbage -> ShelleyToBabbageEraConstraints era => ShelleyToBabbageEra era -> a
ShelleyToBabbageEra era -> a
l ShelleyToBabbageEra era
ShelleyToBabbageEra BabbageEra
ShelleyToBabbageEraBabbage
  ShelleyBasedEra era
ShelleyBasedEraConway -> ConwayEraOnwardsConstraints era => ConwayEraOnwards era -> a
ConwayEraOnwards era -> a
r ConwayEraOnwards era
ConwayEraOnwards ConwayEra
ConwayEraOnwardsConway

shelleyToAlonzoEraToShelleyToBabbageEra
  :: ()
  => ShelleyToAlonzoEra era
  -> ShelleyToBabbageEra era
shelleyToAlonzoEraToShelleyToBabbageEra :: forall era. ShelleyToAlonzoEra era -> ShelleyToBabbageEra era
shelleyToAlonzoEraToShelleyToBabbageEra = \case
  ShelleyToAlonzoEra era
ShelleyToAlonzoEraShelley -> ShelleyToBabbageEra era
ShelleyToBabbageEra ShelleyEra
ShelleyToBabbageEraShelley
  ShelleyToAlonzoEra era
ShelleyToAlonzoEraAllegra -> ShelleyToBabbageEra era
ShelleyToBabbageEra AllegraEra
ShelleyToBabbageEraAllegra
  ShelleyToAlonzoEra era
ShelleyToAlonzoEraMary -> ShelleyToBabbageEra era
ShelleyToBabbageEra MaryEra
ShelleyToBabbageEraMary
  ShelleyToAlonzoEra era
ShelleyToAlonzoEraAlonzo -> ShelleyToBabbageEra era
ShelleyToBabbageEra AlonzoEra
ShelleyToBabbageEraAlonzo

alonzoEraOnwardsToMaryEraOnwards
  :: ()
  => AlonzoEraOnwards era
  -> MaryEraOnwards era
alonzoEraOnwardsToMaryEraOnwards :: forall era. AlonzoEraOnwards era -> MaryEraOnwards era
alonzoEraOnwardsToMaryEraOnwards = \case
  AlonzoEraOnwards era
AlonzoEraOnwardsAlonzo -> MaryEraOnwards era
MaryEraOnwards AlonzoEra
MaryEraOnwardsAlonzo
  AlonzoEraOnwards era
AlonzoEraOnwardsBabbage -> MaryEraOnwards era
MaryEraOnwards BabbageEra
MaryEraOnwardsBabbage
  AlonzoEraOnwards era
AlonzoEraOnwardsConway -> MaryEraOnwards era
MaryEraOnwards ConwayEra
MaryEraOnwardsConway

babbageEraOnwardsToMaryEraOnwards
  :: ()
  => BabbageEraOnwards era
  -> MaryEraOnwards era
babbageEraOnwardsToMaryEraOnwards :: forall era. BabbageEraOnwards era -> MaryEraOnwards era
babbageEraOnwardsToMaryEraOnwards = \case
  BabbageEraOnwards era
BabbageEraOnwardsBabbage -> MaryEraOnwards era
MaryEraOnwards BabbageEra
MaryEraOnwardsBabbage
  BabbageEraOnwards era
BabbageEraOnwardsConway -> MaryEraOnwards era
MaryEraOnwards ConwayEra
MaryEraOnwardsConway

babbageEraOnwardsToAlonzoEraOnwards
  :: ()
  => BabbageEraOnwards era
  -> AlonzoEraOnwards era
babbageEraOnwardsToAlonzoEraOnwards :: forall era. BabbageEraOnwards era -> AlonzoEraOnwards era
babbageEraOnwardsToAlonzoEraOnwards = \case
  BabbageEraOnwards era
BabbageEraOnwardsBabbage -> AlonzoEraOnwards era
AlonzoEraOnwards BabbageEra
AlonzoEraOnwardsBabbage
  BabbageEraOnwards era
BabbageEraOnwardsConway -> AlonzoEraOnwards era
AlonzoEraOnwards ConwayEra
AlonzoEraOnwardsConway