{-# LANGUAGE GADTs #-}
{-# LANGUAGE NamedFieldPuns #-}

module Data.Morpheus.Server.Deriving.Schema.Enum
  ( buildEnumTypeContent,
    defineEnumUnit,
  )
where

import Data.Morpheus.Server.Deriving.Schema.Internal
  ( lookupDescription,
    lookupDirectives,
  )
import Data.Morpheus.Server.Deriving.Utils.Kinded
  ( KindedType (..),
  )
import Data.Morpheus.Server.Types.GQLType
  ( GQLType,
  )
import Data.Morpheus.Server.Types.SchemaT
  ( SchemaT,
    insertType,
  )
import Data.Morpheus.Types.Internal.AST
  ( CONST,
    DataEnumValue (..),
    LEAF,
    TRUE,
    TypeContent (..),
    TypeDefinition,
    TypeName,
    mkEnumContent,
    mkType,
    unitTypeName,
    unpackName,
  )

buildEnumTypeContent :: GQLType a => KindedType kind a -> [TypeName] -> SchemaT c (TypeContent TRUE kind CONST)
buildEnumTypeContent :: forall a (kind :: TypeCategory) (c :: TypeCategory).
GQLType a =>
KindedType kind a
-> [TypeName] -> SchemaT c (TypeContent TRUE kind CONST)
buildEnumTypeContent p :: KindedType kind a
p@KindedType kind a
InputType [TypeName]
enumCons = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall (s :: Stage) (a :: TypeCategory).
DataEnum s -> TypeContent (LEAF <=? a) a s
DataEnum forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (forall a (f :: * -> *).
GQLType a =>
f a -> TypeName -> DataEnumValue CONST
mkEnumValue KindedType kind a
p) [TypeName]
enumCons
buildEnumTypeContent p :: KindedType kind a
p@KindedType kind a
OutputType [TypeName]
enumCons = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall (s :: Stage) (a :: TypeCategory).
DataEnum s -> TypeContent (LEAF <=? a) a s
DataEnum forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (forall a (f :: * -> *).
GQLType a =>
f a -> TypeName -> DataEnumValue CONST
mkEnumValue KindedType kind a
p) [TypeName]
enumCons

mkEnumValue :: GQLType a => f a -> TypeName -> DataEnumValue CONST
mkEnumValue :: forall a (f :: * -> *).
GQLType a =>
f a -> TypeName -> DataEnumValue CONST
mkEnumValue f a
proxy TypeName
enumName =
  DataEnumValue
    { TypeName
enumName :: TypeName
enumName :: TypeName
enumName,
      enumDescription :: Maybe Text
enumDescription = forall a (f :: * -> *). GQLType a => f a -> Text -> Maybe Text
lookupDescription f a
proxy (forall a (t :: NAME). NamePacking a => Name t -> a
unpackName TypeName
enumName),
      enumDirectives :: Directives CONST
enumDirectives = forall a (f :: * -> *).
GQLType a =>
f a -> Text -> Directives CONST
lookupDirectives f a
proxy (forall a (t :: NAME). NamePacking a => Name t -> a
unpackName TypeName
enumName)
    }

defineEnumUnit :: SchemaT cat ()
defineEnumUnit :: forall (cat :: TypeCategory). SchemaT cat ()
defineEnumUnit =
  forall (cat :: TypeCategory) (cat' :: TypeCategory).
TypeDefinition cat CONST -> SchemaT cat' ()
insertType
    ( forall (a :: TypeCategory) (s :: Stage).
TypeName -> TypeContent TRUE a s -> TypeDefinition a s
mkType TypeName
unitTypeName (forall (a :: TypeCategory) (s :: Stage).
(LEAF <=! a) =>
[TypeName] -> TypeContent TRUE a s
mkEnumContent [TypeName
unitTypeName]) ::
        TypeDefinition LEAF CONST
    )