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

module Cardano.Ledger.CanonicalState.Export (
  ExportCanonicalState (..),
  ExportCanonicalNamespace (..),
  addNamespaceToPlan,
) where

import Cardano.Ledger.BaseTypes (
  EpochNo,
 )
import Cardano.SCLS.Internal.Entry.ChunkEntry (ChunkEntry, SomeChunkEntry)
import Cardano.SCLS.Internal.Serializer.Dump.Plan (
  SerializationPlan,
  addNamespacedChunks,
 )
import Cardano.SCLS.NamespaceCodec (KnownNamespace (..))
import Data.MemPack.Extra (RawBytes)
import Data.Proxy (Proxy (Proxy))
import GHC.TypeLits (KnownSymbol)
import Streaming.Prelude (Of, Stream)

class ExportCanonicalState era where
  type State era
  stateSerializationPlan :: Monad m => State era -> SerializationPlan (SomeChunkEntry RawBytes) m
  getEpochNo :: State era -> EpochNo

class KnownNamespace ns => ExportCanonicalNamespace era ns where
  canonicalNamespaceEntries ::
    Monad m =>
    State era ->
    Stream (Of (ChunkEntry (NamespaceKey ns) (NamespaceEntry ns))) m ()

addNamespaceToPlan ::
  forall era ns m.
  (Monad m, KnownSymbol ns, ExportCanonicalNamespace era ns) =>
  State era ->
  SerializationPlan (SomeChunkEntry RawBytes) m ->
  SerializationPlan (SomeChunkEntry RawBytes) m
addNamespaceToPlan :: forall era (ns :: Symbol) (m :: * -> *).
(Monad m, KnownSymbol ns, ExportCanonicalNamespace era ns) =>
State era
-> SerializationPlan (SomeChunkEntry RawBytes) m
-> SerializationPlan (SomeChunkEntry RawBytes) m
addNamespaceToPlan State era
s = Proxy ns
-> Stream
     (Of (ChunkEntry (NamespaceKey ns) (NamespaceEntry ns))) m ()
-> SerializationPlan (SomeChunkEntry RawBytes) m
-> SerializationPlan (SomeChunkEntry RawBytes) m
forall (ns :: Symbol) (m :: * -> *).
(KnownSymbol ns, KnownNamespace ns, Monad m) =>
Proxy ns
-> Stream
     (Of (ChunkEntry (NamespaceKey ns) (NamespaceEntry ns))) m ()
-> SerializationPlan (SomeChunkEntry RawBytes) m
-> SerializationPlan (SomeChunkEntry RawBytes) m
addNamespacedChunks (Proxy ns
forall {k} (t :: k). Proxy t
Proxy :: Proxy ns) (forall era (ns :: Symbol) (m :: * -> *).
(ExportCanonicalNamespace era ns, Monad m) =>
State era
-> Stream
     (Of (ChunkEntry (NamespaceKey ns) (NamespaceEntry ns))) m ()
canonicalNamespaceEntries @era @ns State era
s)