{-# LANGUAGE TypeOperators        #-}
{-# LANGUAGE ScopedTypeVariables  #-}
{-# LANGUAGE BangPatterns #-}

module Gargantext.API.Node.ShareURL where

import Control.Lens
import Data.Text qualified as T
import Data.Validity qualified as V
import Gargantext.API.Admin.Types (appPort, settings, Settings)
import Gargantext.API.Prelude
import Gargantext.API.Routes.Named.Share qualified as Named
import Gargantext.Core.Config (gc_url, GargConfig)
import Gargantext.Core.Types (NodeType, NodeId, unNodeId, _ValidationError)
import Gargantext.Database.Prelude (HasConfig (hasConfig), CmdCommon)
import Gargantext.Prelude
import Network.URI (parseURI)
import Prelude (String)
import Servant.Server.Generic (AsServerT)

shareURL :: IsGargServer env err m => Named.ShareURL (AsServerT m)
shareURL = Named.ShareURL getUrl

getUrl :: (IsGargServer env err m, CmdCommon env)
       => Maybe NodeType
       -> Maybe NodeId
       -> m Named.ShareLink
getUrl nt id = do
  -- TODO add check that the node is able to be shared (in a shared folder)
  gc      <- view hasConfig
  urlPort <- view settings
  case get_url nt id gc urlPort of
    Left err        -> throwError $ _ValidationError # (V.check False err)
    Right shareLink -> pure shareLink

get_url :: Maybe NodeType
        -> Maybe NodeId
        -> GargConfig
        -> Settings
        -> Either String Named.ShareLink
get_url nt id gc stgs = do
  let urlHost = T.unpack $ gc ^. gc_url
  let urlPort = stgs ^. appPort
  t <- maybe (Left "Invalid node Type") Right nt
  i <- maybe (Left "Invalid node ID")   Right id

  -- Include the port the server is running on if this is
  -- localhost, so that share URLs would work out of the box.
  let !rawURL
        | "localhost" `isInfixOf` urlHost
        = urlHost <> ":" <> show urlPort <> "/#/share/" <> show t <> "/" <> show (unNodeId i)
        | otherwise
        = urlHost <> "/#/share/" <> show t <> "/" <> show (unNodeId i)
  maybe (Left $ "Couldn't construct a valid share URL from '" <> rawURL <> "'")
        (Right . Named.ShareLink)
        (parseURI rawURL)
