module Codec.EBML.Schema where

import Data.Binary.Get (Get)
import Data.Map.Strict (Map)
import Data.Map.Strict qualified as Map
import Data.Text (Text)

import Codec.EBML.Element

{- | EBML schema definition.

Note that this is missing:

- min/max occurrence constraint.
- default value.
- element path.
-}
data EBMLSchema = EBMLSchema
    { EBMLSchema -> Text
name :: Text
    -- ^ The element name.
    , EBMLSchema -> EBMLID
eid :: EBMLID
    -- ^ The element id.
    , EBMLSchema -> EBMLSchemas -> EBMLElementHeader -> Get EBMLValue
decode :: EBMLSchemas -> EBMLElementHeader -> Get EBMLValue
    -- ^ How to decode the element value.
    }

newtype EBMLSchemas = EBMLSchemas (Map EBMLID EBMLSchema)

-- | Combine a list of schema for decoder.
compileSchemas :: [EBMLSchema] -> EBMLSchemas
compileSchemas :: [EBMLSchema] -> EBMLSchemas
compileSchemas = Map EBMLID EBMLSchema -> EBMLSchemas
EBMLSchemas forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map forall {b} {a}. HasField "eid" b a => b -> (a, b)
toKV
  where
    toKV :: b -> (a, b)
toKV b
schema = (b
schema.eid, b
schema)

lookupSchema :: EBMLID -> EBMLSchemas -> Maybe EBMLSchema
lookupSchema :: EBMLID -> EBMLSchemas -> Maybe EBMLSchema
lookupSchema EBMLID
eid (EBMLSchemas Map EBMLID EBMLSchema
schemas) = forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup EBMLID
eid Map EBMLID EBMLSchema
schemas