{-# LANGUAGE TypeOperators #-}

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 (Generic)
import Gargantext.API.Viz.Types (PhyloData(..))
import Gargantext.API.Worker (WorkerAPI)
import Gargantext.Core.Types (ListId, NodeId)
import Gargantext.Core.Viz.Graph.Types (Graph, GraphLegendAPI, GraphVersions(..), HyperdataGraphAPI)
import Gargantext.Core.Viz.LegacyPhylo (Level)
import Gargantext.Core.Viz.Phylo.Legacy.LegacyMain (MinSizeBranch)
import Servant
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
  , updateGraphLegendEp :: mode :- "legend" :> ReqBody '[JSON] GraphLegendAPI :> Post '[JSON] NodeId
  } deriving Generic


newtype GraphAsyncAPI mode = GraphAsyncAPI
  { recomputeGraphEp :: mode :- Summary "Recompute graph"
                             :> "recompute"
                             :> NamedRoutes (WorkerAPI '[JSON] ())
  } 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