content: {-# LANGUAGE DataKinds #-}
  {-# LANGUAGE DeriveAnyClass #-}
  {-# LANGUAGE DeriveGeneric #-}
  {-# LANGUAGE DuplicateRecordFields #-}
  {-# LANGUAGE OverloadedStrings #-}
  {-# LANGUAGE TemplateHaskellQuotes #-}
  {-# LANGUAGE TypeFamilies #-}
  
  module Feature.Directive.Definition
    ( api,
    )
  where
  
  import Data.Kind (Type)
  import Data.Morpheus.Server (interpreter)
  import Data.Morpheus.Server.Types
    ( DIRECTIVE,
      Deprecated (..),
      DirectiveLocation (..),
      GQLDirective (..),
      GQLRequest,
      GQLResponse,
      GQLType (..),
      Prefixes (..),
      RootResolver (..),
      Suffixes (..),
      Undefined,
      VisitType (..),
      defaultRootResolver,
      enumDirective',
      fieldDirective',
      typeDirective,
    )
  import Data.Text (Text)
  import GHC.Generics (Generic)
  
  data MythologyDeity' = MythologyDeity'
    { deityName :: Text,
      deprecatedField :: Maybe Text,
      deprecatedFieldWithReason :: Bool
    }
    deriving (Generic)
  
  data Power = Power
    { name :: Text,
      isLimited :: Bool
    }
    deriving (Generic)
  
  instance GQLType Power where
    type KIND Power = DIRECTIVE
  
  instance GQLDirective Power where
    type DIRECTIVE_LOCATIONS Power = '[ 'LOCATION_OBJECT]
  
  instance VisitType Power where
    visitTypeName _ _ = id
  
  instance GQLType MythologyDeity' where
    directives _ =
      typeDirective Power {name = "Lightning bolts", isLimited = False}
        <> typeDirective Prefixes {addPrefix = "", removePrefix = "Mythology"}
        <> typeDirective Suffixes {addSuffix = "", removeSuffix = "'"}
        <> fieldDirective' 'deprecatedField Deprecated {reason = Nothing}
        <> fieldDirective' 'deprecatedFieldWithReason Deprecated {reason = Just "this should be deprecated"}
  
  data City
    = Athens
    | Sparta
    | Corinth
    | Delphi
    | Argos
    deriving
      (Generic)
  
  instance GQLType City where
    directives _ =
      enumDirective' 'Sparta Deprecated {reason = Nothing}
        <> enumDirective' 'Delphi Deprecated {reason = Just "oracle left the place"}
        <> enumDirective' 'Argos Deprecated {reason = Just "for some reason"}
  
  data Query (m :: Type -> Type) = Query
    { deity :: MythologyDeity',
      city :: City
    }
    deriving (Generic, GQLType)
  
  root :: RootResolver IO () Query Undefined Undefined
  root =
    defaultRootResolver
      { queryResolver =
          Query
            { deity =
                MythologyDeity'
                  { deityName = "morpheus",
                    deprecatedField = Nothing,
                    deprecatedFieldWithReason = False
                  },
              city = Corinth
            }
      }
  
  api :: GQLRequest -> IO GQLResponse
  api = interpreter root
  