{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DeriveGeneric #-}

module Gargantext.API.Routes.Named.Viz (
  -- * Routes types
    PhyloAPI(..)
  , GetPhylo(..)
  , PostPhylo(..)
  , GraphAPI(..)
  , GraphAsyncAPI(..)
  , GraphVersionsAPI(..)
  , PhyloExportAPI(..)
  , PhyloExportEndpoints(..)

  -- * API types (appears in the routes)
  , PhyloData(..)
  , GraphVersions(..)
  ) where

import Data.Aeson ( Value )
import Data.Text (Text)
import GHC.Generics
import Gargantext.API.Admin.Orchestrator.Types ( JobLog )
import Gargantext.API.Viz.Types (PhyloData(..))
import Gargantext.Core.Types
import Gargantext.Core.Viz.Graph.Types
import Gargantext.Core.Viz.LegacyPhylo (Level)
import Gargantext.Core.Viz.Phylo.Legacy.LegacyMain (MinSizeBranch)
import Servant
import Servant.Job.Async (AsyncJobsAPI)
import Servant.XML.Conduit (XML)


data PhyloAPI mode = PhyloAPI
  { getPhyloEp  :: mode :- Summary "Phylo API" :> NamedRoutes GetPhylo
  , postPhyloEp :: mode :- NamedRoutes PostPhylo
  } deriving Generic


newtype GetPhylo mode = GetPhylo
  { getPhyloDataEp :: mode :- QueryParam "listId"      ListId
                           :> QueryParam "level"       Level
                           :> QueryParam "minSizeBranch" MinSizeBranch
                           :> Get '[JSON] PhyloData
  } deriving Generic


newtype PostPhylo mode = PostPhylo
  { postPhyloByListIdEp :: mode :- QueryParam "listId" ListId :> (Post '[JSON] NodeId)
  } deriving Generic


-- | There is no Delete specific API for Graph since it can be deleted
-- as simple Node.
data GraphAPI mode = GraphAPI
  { getGraphEp       :: mode :- Get '[JSON] HyperdataGraphAPI
  , getGraphAsyncEp  :: mode :- "async" :> NamedRoutes GraphAsyncAPI
  , cloneGraphEp     :: mode :- "clone" :> ReqBody '[JSON] HyperdataGraphAPI :> Post '[JSON] NodeId
  , gexfEp           :: mode :- "gexf" :> Get '[XML] (Headers '[Servant.Header "Content-Disposition" Text] Graph)
  , graphVersionsAPI :: mode :- "versions" :> NamedRoutes GraphVersionsAPI
  } deriving Generic


newtype GraphAsyncAPI mode = GraphAsyncAPI
  { recomputeGraphEp :: mode :- Summary "Recompute graph"
                             :> "recompute"
                             :> AsyncJobsAPI JobLog () JobLog
  } deriving Generic


data GraphVersionsAPI mode = GraphVersionsAPI
  { getGraphVersionsEp :: mode :- Summary "Graph versions" :> Get '[JSON] GraphVersions
  , recomputeGraphVersionEp :: mode :- Summary "Recompute graph version" :> Post '[JSON] Graph
  } deriving Generic

newtype PhyloExportAPI mode = PhyloExportAPI
  { phyloExportEndpoints :: mode :- "export" :> NamedRoutes PhyloExportEndpoints
  } deriving Generic

data PhyloExportEndpoints mode = PhyloExportEndpoints
  { exportPhyloJSONEp :: mode :- "json" :> Get '[JSON] (Headers '[Servant.Header "Content-Disposition" Text] Value)
  , exportPhyloDotEp  :: mode :- "dot"  :> Get '[JSON] (Headers '[Servant.Header "Content-Disposition" Text] Text)
  } deriving Generic
