{-# LANGUAGE TypeApplications    #-}
{-# LANGUAGE TypeOperators       #-}
{-# LANGUAGE LambdaCase          #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -Wno-orphans     #-}

module CLI.Server.Routes (
    routesCLI
  , routesCmd
  ) where

import CLI.Types
import Data.Aeson.Encode.Pretty
import Data.ByteString qualified as B
import Data.ByteString.Lazy qualified as BL
import Gargantext.API.Routes.Named
import Options.Applicative
import Prelude
import Servant.API
import Servant.API.Routes
import Servant.API.WebSocket qualified as WS (WebSocketPending)
import Servant.Auth qualified as Servant

routesCmd :: Mod CommandFields CLI
routesCmd = command "routes" (info (helper <*> (fmap CLISub $ fmap CCMD_routes routesParser))
                                   (progDesc "Server routes related commands."))

routesParser :: Parser CLIRoutes
routesParser = hsubparser (
  (command "list" (info (helper <*> list_p)
                                   (progDesc "List all the available routes, computed by the Routes types."))) <>
  (command "export" (info (helper <*> export_p)
                                   (progDesc "Exports all the routes into a file, for golden-diff testing.")))
  )

list_p :: Parser CLIRoutes
list_p = pure CLIR_list

export_p :: Parser CLIRoutes
export_p = CLIR_export <$>
  strOption ( long "file" <> metavar "output.json" <> help "Export the routes to a file." )

instance HasRoutes api => HasRoutes (Servant.Auth xs a :> api) where
  getRoutes = getRoutes @api

instance HasRoutes WS.WebSocketPending where
  getRoutes = []

instance HasRoutes Raw where
  getRoutes = []

routesCLI :: CLIRoutes -> IO ()
routesCLI = \case
  CLIR_list
    -> printRoutes @(NamedRoutes API)
  (CLIR_export filePath)
    -> B.writeFile filePath . BL.toStrict $ encodePretty (getRoutes @(NamedRoutes API))
