{-|
Module      : Gargantext.Database.Action.Delete
Description :
Copyright   : (c) CNRS, 2017-Present
License     : AGPL + CECILL v3
Maintainer  : team@gargantext.org
Stability   : experimental
Portability : POSIX

TODO: right managements of nodes children of node Team
-- TODO add proper Right Management Type

TODO: NodeError

-}

{-# LANGUAGE ScopedTypeVariables #-}

module Gargantext.Database.Action.Delete
  where

import Control.Lens (view)
import Data.Text (unpack)
import Gargantext.Core (HasDBid(..))
import Gargantext.Core.Notifications.CentralExchange.Types (ce_notify, CEMessage(..), HasCentralExchangeNotification)
import Gargantext.Core.Types.Individu (User(..))
import Gargantext.Database.Action.Share (delFolderTeam)
import Gargantext.Database.Action.User (getUserId)
import Gargantext.Database.Admin.Types.Hyperdata.File ( HyperdataFile(..) )
import Gargantext.Database.Admin.Types.Node ( NodeId, NodeType(..) ) -- (NodeType(..))
import Gargantext.Database.GargDB qualified as GargDB
import Gargantext.Database.Prelude
import Gargantext.Database.Query.Table.Node (getNodeWith)
import Gargantext.Database.Query.Table.Node qualified as N (getNode, deleteNode)
import Gargantext.Database.Query.Table.Node.Error (HasNodeError, nodeErrorWith)
import Gargantext.Database.Schema.Node
import Gargantext.Prelude

------------------------------------------------------------------------
-- TODO
-- Delete Corpus children accoring its types
-- Delete NodeList (NodeStory + cbor file)
deleteNode :: (HasNodeError err
              , IsDBCmd env err m
              , HasCentralExchangeNotification env
              )
           => User
           -> NodeId
           -> m Int
deleteNode u nodeId = do
  (num, upd_node, cleanup) <- runDBTx $ do
    node' <- N.getNode nodeId
    (rows, clean_it) <- case view node_typename node' of
      nt | nt == toDBid NodeUser -> nodeErrorWith "[G.D.A.D.deleteNode] Not allowed to delete NodeUser (yet)"
      nt | nt == toDBid NodeTeam -> do
        uId   <- getUserId u
        if _node_user_id node' == uId
          then do
            r <- N.deleteNode nodeId
            pure (r, pure ())
          else do
            r <- delFolderTeam u nodeId
            pure (r, pure ())
      nt | nt == toDBid NodeFile -> do
        node <- getNodeWith nodeId (Proxy :: Proxy HyperdataFile)
        let (HyperdataFile { _hff_path = path }) = node ^. node_hyperdata
        r <- N.deleteNode nodeId
        pure (r, GargDB.rmFile $ unpack path)
      _  -> do
        r <- N.deleteNode nodeId
        pure (r, pure ())
    pure (rows, node', clean_it)

  -- | Node was deleted, refresh its parent (if exists)
  -- mapM_ (CE.ce_notify . CE.UpdateTreeFirstLevel) nodeIds
  cleanup
  for_ (view node_parent_id upd_node) $ ce_notify . UpdateTreeFirstLevel
  pure num
