{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE InstanceSigs #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# LANGUAGE ViewPatterns #-}

module Gargantext.API.Routes.Client where

import Conduit qualified as C
import Data.Proxy
import Data.Text.Encoding qualified as TE
import Gargantext.API.Admin.Auth.Types qualified as Auth
import Gargantext.API.Errors (GargErrorScheme(..))
import Gargantext.API.Routes.Named
import Gargantext.API.Routes.Named.Node
import Gargantext.API.Routes.Named.Private
import Gargantext.API.Routes.Named.Remote qualified as Named
import Gargantext.Database.Admin.Types.Node
import Gargantext.Prelude
import Network.HTTP.Types qualified as H
import Servant.API.WebSocket qualified as WS
import Servant.Auth.Client qualified as S
import Servant.Client.Core
import Servant.Client.Generic (genericClient)
import Servant.Client.Streaming
import Servant.Conduit ()

instance RunClient m => HasClient m WS.WebSocketPending where
  type Client m WS.WebSocketPending = H.Method ->  m ()

  clientWithRoute :: Proxy m -> Proxy WS.WebSocketPending -> Request -> Client m WS.WebSocketPending
  clientWithRoute _pm Proxy _req _httpMethod = do
    panicTrace "[WebSocket client] this is not implemented!"

  hoistClientMonad _ _ f cl = \meth -> f (cl meth)

-- | The client for the full API. It also serves as a \"proof\" that our
-- whole API has all the required instances to be used in a client.
clientRoutes :: API (AsClientT ClientM)
clientRoutes = genericClient

remoteImportClient :: Auth.Token
                   -> C.ConduitT () Named.RemoteBinaryData IO ()
                   -> ClientM [NodeId]
remoteImportClient (S.Token . TE.encodeUtf8 -> token) c =
  clientRoutes & apiWithCustomErrorScheme
               & ($ GES_new)
               & backendAPI
               & backendAPI'
               & mkBackEndAPI
               & gargAPIVersion
               & gargPrivateAPI
               & mkPrivateAPI
               & ($ token)
               & nodeEp
               & nodeRemoteImportAPI
               & Named.remoteImportEp
               & ($ c)

remoteExportClient :: Auth.Token
                   -> NodeId
                   -> Named.RemoteExportRequest
                   -> ClientM [NodeId]
remoteExportClient (S.Token . TE.encodeUtf8 -> token) nodeId r =
  clientRoutes & apiWithCustomErrorScheme
               & ($ GES_new)
               & backendAPI
               & backendAPI'
               & mkBackEndAPI
               & gargAPIVersion
               & gargPrivateAPI
               & mkPrivateAPI
               & ($ token)
               & nodeEp
               & nodeEndpointAPI
               & ($ nodeId)
               & remoteExportAPI
               & Named.remoteExportEp
               & ($ r)
