{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE NoImplicitPrelude #-}

module Data.Morpheus.Client
  ( raw,
    Fetch (..),
    FetchError (..),
    ScalarValue (..),
    DecodeScalar (..),
    EncodeScalar (..),
    ID (..),
    declareGlobalTypes,
    declareGlobalTypesByName,
    declareLocalTypes,
    declareLocalTypesInline,
    clientTypeDeclarations,
    -- Fetch API
    GQLClient,
    GQLClientResult,
    ResponseStream,
    withHeaders,
    request,
    forEach,
    single,
    -- DEPRECATED EXPORTS
    gql,
    defineByDocument,
    defineByDocumentFile,
    defineByDocumentFile',
    defineByIntrospection,
    defineByIntrospectionFile,
    defineByIntrospectionFile',
  )
where

import Data.ByteString.Lazy (ByteString)
import qualified Data.ByteString.Lazy as L
  ( readFile,
  )
import Data.Morpheus.Client.Declare
  ( clientTypeDeclarations,
    declareGlobalTypes,
    declareGlobalTypesByName,
    declareLocalTypes,
    declareLocalTypesInline,
    internalLegacyLocalDeclareTypes,
    raw,
  )
import Data.Morpheus.Client.Fetch
  ( Fetch (..),
  )
import Data.Morpheus.Client.Fetch.ResponseStream
  ( GQLClient,
    ResponseStream,
    forEach,
    request,
    single,
    withHeaders,
  )
import Data.Morpheus.Client.Internal.Types
  ( ExecutableSource,
    FetchError (..),
    GQLClientResult,
    SchemaSource (..),
  )
import Data.Morpheus.Types.GQLScalar
  ( DecodeScalar (..),
    EncodeScalar (..),
  )
import Data.Morpheus.Types.ID (ID (..))
import Data.Morpheus.Types.Internal.AST
  ( ScalarValue (..),
  )
import Language.Haskell.TH
import Language.Haskell.TH.Quote (QuasiQuoter)
import Language.Haskell.TH.Syntax
  ( qAddDependentFile,
  )
import Relude hiding (ByteString)

{-# DEPRECATED gql "use raw" #-}
gql :: QuasiQuoter
gql :: QuasiQuoter
gql = QuasiQuoter
raw

-- DEPRECATED: Legacy Code Exports

{-# DEPRECATED defineByDocumentFile' "use declareLocalTypes" #-}

-- | This variant exposes 'Q FilePath' enabling the use of TH to generate the 'FilePath'. For example, https://hackage.haskell.org/package/file-embed-0.0.13.0/docs/Data-FileEmbed.html#v:makeRelativeToProject can be used to handle multi package projects more reliably.
defineByDocumentFile' :: Q FilePath -> ExecutableSource -> Q [Dec]
defineByDocumentFile' :: Q FilePath -> ExecutableSource -> Q [Dec]
defineByDocumentFile' Q FilePath
qFilePath ExecutableSource
args = Q FilePath
qFilePath forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a b c. (a -> b -> c) -> b -> a -> c
flip FilePath -> ExecutableSource -> Q [Dec]
defineByDocumentFile ExecutableSource
args

{-# DEPRECATED defineByIntrospectionFile' "use declareLocalTypes" #-}

-- | This variant exposes 'Q FilePath' enabling the use of TH to generate the 'FilePath'. For example, https://hackage.haskell.org/package/file-embed-0.0.13.0/docs/Data-FileEmbed.html#v:makeRelativeToProject can be used to handle multi package projects more reliably.
defineByIntrospectionFile' :: Q FilePath -> ExecutableSource -> Q [Dec]
defineByIntrospectionFile' :: Q FilePath -> ExecutableSource -> Q [Dec]
defineByIntrospectionFile' Q FilePath
path ExecutableSource
args = Q FilePath
path forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a b c. (a -> b -> c) -> b -> a -> c
flip FilePath -> ExecutableSource -> Q [Dec]
defineByIntrospectionFile ExecutableSource
args

-- with file

{-# DEPRECATED defineByIntrospectionFile "use declareLocalTypes" #-}
defineByIntrospectionFile :: FilePath -> ExecutableSource -> Q [Dec]
defineByIntrospectionFile :: FilePath -> ExecutableSource -> Q [Dec]
defineByIntrospectionFile FilePath
filePath ExecutableSource
args = do
  forall (m :: * -> *). Quasi m => FilePath -> m ()
qAddDependentFile FilePath
filePath
  IO ByteString -> ExecutableSource -> Q [Dec]
defineByIntrospection (FilePath -> IO ByteString
L.readFile FilePath
filePath) ExecutableSource
args

{-# DEPRECATED defineByDocumentFile "use declareLocalTypes" #-}
defineByDocumentFile :: FilePath -> ExecutableSource -> Q [Dec]
defineByDocumentFile :: FilePath -> ExecutableSource -> Q [Dec]
defineByDocumentFile FilePath
filePath ExecutableSource
args = do
  forall (m :: * -> *). Quasi m => FilePath -> m ()
qAddDependentFile FilePath
filePath
  IO ByteString -> ExecutableSource -> Q [Dec]
defineByDocument (FilePath -> IO ByteString
L.readFile FilePath
filePath) ExecutableSource
args

-- direct

{-# DEPRECATED defineByDocument "use clientTypeDeclarations" #-}
defineByDocument :: IO ByteString -> ExecutableSource -> Q [Dec]
defineByDocument :: IO ByteString -> ExecutableSource -> Q [Dec]
defineByDocument IO ByteString
doc = IO SchemaSource -> ExecutableSource -> Q [Dec]
internalLegacyLocalDeclareTypes (ByteString -> SchemaSource
GQL forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO ByteString
doc)

{-# DEPRECATED defineByIntrospection "use clientTypeDeclarations" #-}
defineByIntrospection :: IO ByteString -> ExecutableSource -> Q [Dec]
defineByIntrospection :: IO ByteString -> ExecutableSource -> Q [Dec]
defineByIntrospection IO ByteString
doc = IO SchemaSource -> ExecutableSource -> Q [Dec]
internalLegacyLocalDeclareTypes (ByteString -> SchemaSource
JSON forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO ByteString
doc)