packages feed

nomyx-api-0.1.0: src/Nomyx/Api/Api.hs

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}

module Nomyx.Api.Api
     where

import           GHC.Generics
import           Data.Proxy
import           Data.Yaml
import qualified Data.ByteString.Char8 as B
import           Data.Maybe (fromMaybe)
import           Data.List (intercalate)
import           Data.Maybe
import           Data.Typeable
import qualified Data.Text as T
import           Data.Swagger
import           Data.Swagger.Schema
import           Servant.API
import           Servant.Client
import           Servant
import           Network.URI (URI (..), URIAuth (..), parseURI)
import           Network.Wai.Parse
import           Nomyx.Api.Model.Player
import           Nomyx.Api.Model.Error
import           Nomyx.Api.Model.NewPlayer
import           Nomyx.Core.Session hiding (getModules)
import           Nomyx.Core.Types
import           Nomyx.Core.Profile
import           Nomyx.Language.Types
import           Control.Concurrent.STM
import           Control.Monad.State
import           Control.Monad.Trans.Either
import           Control.Monad.Except
import           System.Log.Logger
import           Test.QuickCheck

-- * API definition

type NomyxApi = PlayerApi :<|> RuleTemplateApi

type PlayerApi =  "players" :>                                   Get    '[JSON] [ProfileData] 
             :<|> "players" :> ReqBody '[JSON] PlayerSettings :> Post   '[JSON] ProfileData 
             :<|> "players" :> Capture "id" Int               :> Get    '[JSON] ProfileData
             :<|> "players" :> Capture "id" Int               :> Delete '[JSON] ()


type RuleTemplateApi =  "templates" :> BasicAuth "foo-realm" PlayerNumber :>                            Get '[JSON] Library  -- get all templates
                   :<|> "templates" :> BasicAuth "foo-realm" PlayerNumber :> ReqBody '[JSON] Library :> Put '[JSON] ()       -- replace all templates

nomyxApi :: Proxy NomyxApi
nomyxApi = Proxy

serverPath :: String
serverPath = "https://api.nomyx.net/v1"

server :: TVar Session -> Server NomyxApi
server tv = ((playersGet tv)   :<|> (playersPost tv)   :<|> (playerGet tv) :<|> (playerDelete tv))
       :<|> ((templatesGet tv) :<|> (templatesPut tv))

-- * Players API

playersGet :: TVar Session -> ExceptT ServantErr IO [ProfileData]
playersGet tv = do
   s <- liftIO $ atomically $ readTVar tv
   pds <- liftIO $ getAllProfiles s
   return pds

playersPost :: TVar Session -> PlayerSettings -> ExceptT ServantErr IO ProfileData
playersPost tv ps = do
   liftIO $ updateSession tv (newPlayer 2 ps)
   s <- liftIO $ atomically $ readTVar tv
   pds <- liftIO $ getAllProfiles s
   return $ head pds

playerGet :: TVar Session -> PlayerNumber -> ExceptT ServantErr IO ProfileData
playerGet tv pn = do
   s <- liftIO $ atomically $ readTVar tv
   mpd <- liftIO $ getProfile s pn
   case mpd of
     Just pd -> return pd
     Nothing -> throwError $ err410 { errBody = "Player does not exist." }

playerDelete :: TVar Session -> PlayerNumber -> ExceptT ServantErr IO ()
playerDelete tv pn = error "not supported"

-- * Templates API

templatesGet :: TVar Session -> PlayerNumber -> ExceptT ServantErr IO Library
templatesGet tv _ = do
   s <- liftIO $ atomically $ readTVar tv
   return $ _mLibrary $ _multi s

templatesPost :: TVar Session -> PlayerNumber -> RuleTemplate -> ExceptT ServantErr IO ()
templatesPost tv _ rt = do
   liftIO $ updateSession tv (newRuleTemplate 1 rt)
   return ()

templatesPut :: TVar Session -> PlayerNumber -> Library -> ExceptT ServantErr IO ()
templatesPut tv pn lib = liftIO $ do
   debug $ "templatesPut library: " ++ (show lib)
   updateSession tv (updateLibrary pn lib)
   return ()

debug, info :: (MonadIO m) => String -> m ()
debug s = liftIO $ debugM "Nomyx.Api.Api" s
info s = liftIO $ infoM "Nomyx.Api.Api" s