{-# LANGUAGE InstanceSigs    #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ViewPatterns #-}


module Test.API.Routes where

import Data.Text.Encoding qualified as TE
import Fmt (Builder, (+|), (|+))
import Gargantext.API.Admin.Auth.Types (AuthRequest, AuthResponse, Token)
import Gargantext.API.Errors
import Gargantext.API.Ngrams.Types ( NgramsTable, NgramsTablePatch, OrderBy, TabType, Versioned, VersionedWithCount )
import Gargantext.API.Routes.Named
import Gargantext.API.Routes.Named.Node
import Gargantext.API.Routes.Named.Private hiding (tableNgramsAPI)
import Gargantext.API.Routes.Named.Table
import Gargantext.API.Types () -- MimeUnrender instances
import Gargantext.Core.Types (ListId, NodeId)
import Gargantext.Core.Types.Main (ListType)
import Gargantext.Core.Types.Query (Limit, MaxSize, MinSize, Offset)
import Gargantext.Prelude
import Network.HTTP.Types qualified as H
import Network.Wai.Handler.Warp (Port)
import Servant.API.WebSocket qualified as WS
import Servant.Auth.Client qualified as S
import Servant.Client (ClientM)
import Servant.Client.Core (RunClient, HasClient(..), Request)
import Servant.Client.Generic ( genericClient, AsClientT )


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!"
    return ()

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

    
-- This is for requests made by http.client directly to hand-crafted URLs    
curApi :: Builder
curApi = "v1.0"

mkUrl :: Port -> Builder -> ByteString
mkUrl _port urlPiece =
  "/api/" +| curApi |+ urlPiece


-- | 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

-- This is for Servant.Client requests
auth_api :: AuthRequest -> ClientM AuthResponse
auth_api = clientRoutes & apiWithCustomErrorScheme
                        & ($ GES_new)
                        & backendAPI
                        & backendAPI'
                        & mkBackEndAPI
                        & gargAPIVersion
                        & gargAuthAPI
                        & authEp

table_ngrams_get_api :: Token
                     -> NodeId
                     -> TabType
                     -> ListId
                     -> Limit
                     -> Maybe Offset
                     -> Maybe ListType
                     -> Maybe MinSize
                     -> Maybe MaxSize
                     -> Maybe OrderBy
                     -> Maybe Text
                     -> ClientM (VersionedWithCount NgramsTable)
table_ngrams_get_api (toServantToken -> token) nodeId =
  clientRoutes & apiWithCustomErrorScheme
               & ($ GES_new)
               & backendAPI
               & backendAPI'
               & mkBackEndAPI
               & gargAPIVersion
               & gargPrivateAPI
               & mkPrivateAPI
               & ($ token)
               & nodeEp
               & nodeEndpointAPI
               & ($ nodeId)
               & tableNgramsAPI
               & tableNgramsGetAPI
               & getNgramsTableEp

toServantToken :: Token -> S.Token
toServantToken = S.Token . TE.encodeUtf8

table_ngrams_put_api :: Token
                     -> NodeId
                     -> TabType
                     -> ListId
                     -> Versioned NgramsTablePatch
                     -> ClientM (Versioned NgramsTablePatch)
table_ngrams_put_api (toServantToken -> token) nodeId =
  clientRoutes & apiWithCustomErrorScheme
               & ($ GES_new)
               & backendAPI
               & backendAPI'
               & mkBackEndAPI
               & gargAPIVersion
               & gargPrivateAPI
               & mkPrivateAPI
               & ($ token)
               & nodeEp
               & nodeEndpointAPI
               & ($ nodeId)
               & tableNgramsAPI
               & tableNgramsPutAPI
               & putNgramsTableEp