{-# LANGUAGE DeriveGeneric #-}

-- |
-- Module      : Docs.Document
-- Description : Document and Related Datatypes
-- License     : AGPL-3
-- Maintainer  : stu235271@mail.uni-kiel.de
--               stu236925@mail.uni-kiel.de
--
-- This module contains the definition of a @Document@ datatype as well as
-- related datatypes
module Docs.Document
    ( DocumentID (..)
    , Document (..)
    ) where

import Data.Proxy (Proxy (..))
import Data.Text (Text)
import Data.Time (UTCTime)

import GHC.Generics (Generic)
import GHC.Int (Int64)

import Web.HttpApiData (FromHttpApiData (..))

import Control.Lens ((&), (?~))
import Data.Aeson (FromJSON (..), ToJSON (..))
import Data.OpenApi
    ( OpenApiType (..)
    , ToParamSchema (..)
    , ToSchema (..)
    , exclusiveMinimum
    , minimum_
    , type_
    )

import UserManagement.Group (GroupID)

import Docs.UserRef (UserRef)

-- | ID for a document
newtype DocumentID = DocumentID
    { DocumentID -> Int64
unDocumentID :: Int64
    }
    deriving (DocumentID -> DocumentID -> Bool
(DocumentID -> DocumentID -> Bool)
-> (DocumentID -> DocumentID -> Bool) -> Eq DocumentID
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DocumentID -> DocumentID -> Bool
== :: DocumentID -> DocumentID -> Bool
$c/= :: DocumentID -> DocumentID -> Bool
/= :: DocumentID -> DocumentID -> Bool
Eq, Int -> DocumentID -> ShowS
[DocumentID] -> ShowS
DocumentID -> String
(Int -> DocumentID -> ShowS)
-> (DocumentID -> String)
-> ([DocumentID] -> ShowS)
-> Show DocumentID
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DocumentID -> ShowS
showsPrec :: Int -> DocumentID -> ShowS
$cshow :: DocumentID -> String
show :: DocumentID -> String
$cshowList :: [DocumentID] -> ShowS
showList :: [DocumentID] -> ShowS
Show)

instance ToJSON DocumentID where
    toJSON :: DocumentID -> Value
toJSON = Int64 -> Value
forall a. ToJSON a => a -> Value
toJSON (Int64 -> Value) -> (DocumentID -> Int64) -> DocumentID -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DocumentID -> Int64
unDocumentID

instance FromJSON DocumentID where
    parseJSON :: Value -> Parser DocumentID
parseJSON = (Int64 -> DocumentID) -> Parser Int64 -> Parser DocumentID
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int64 -> DocumentID
DocumentID (Parser Int64 -> Parser DocumentID)
-> (Value -> Parser Int64) -> Value -> Parser DocumentID
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Parser Int64
forall a. FromJSON a => Value -> Parser a
parseJSON

instance ToSchema DocumentID where
    declareNamedSchema :: Proxy DocumentID -> Declare (Definitions Schema) NamedSchema
declareNamedSchema Proxy DocumentID
_ = Proxy Int64 -> Declare (Definitions Schema) NamedSchema
forall a.
ToSchema a =>
Proxy a -> Declare (Definitions Schema) NamedSchema
declareNamedSchema (Proxy Int64
forall {k} (t :: k). Proxy t
Proxy :: Proxy Int64)

instance ToParamSchema DocumentID where
    toParamSchema :: Proxy DocumentID -> Schema
toParamSchema Proxy DocumentID
_ =
        Schema
forall a. Monoid a => a
mempty
            Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe OpenApiType -> Identity (Maybe OpenApiType))
-> Schema -> Identity Schema
forall s a. HasType s a => Lens' s a
Lens' Schema (Maybe OpenApiType)
type_ ((Maybe OpenApiType -> Identity (Maybe OpenApiType))
 -> Schema -> Identity Schema)
-> OpenApiType -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ OpenApiType
OpenApiInteger
            Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe Scientific -> Identity (Maybe Scientific))
-> Schema -> Identity Schema
forall s a. HasMinimum s a => Lens' s a
Lens' Schema (Maybe Scientific)
minimum_ ((Maybe Scientific -> Identity (Maybe Scientific))
 -> Schema -> Identity Schema)
-> Scientific -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ Scientific
0
            Schema -> (Schema -> Schema) -> Schema
forall a b. a -> (a -> b) -> b
& (Maybe Bool -> Identity (Maybe Bool)) -> Schema -> Identity Schema
forall s a. HasExclusiveMinimum s a => Lens' s a
Lens' Schema (Maybe Bool)
exclusiveMinimum ((Maybe Bool -> Identity (Maybe Bool))
 -> Schema -> Identity Schema)
-> Bool -> Schema -> Schema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ Bool
False

instance FromHttpApiData DocumentID where
    parseUrlPiece :: Text -> Either Text DocumentID
parseUrlPiece = (Int64 -> DocumentID
DocumentID (Int64 -> DocumentID)
-> Either Text Int64 -> Either Text DocumentID
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>) (Either Text Int64 -> Either Text DocumentID)
-> (Text -> Either Text Int64) -> Text -> Either Text DocumentID
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either Text Int64
forall a. FromHttpApiData a => Text -> Either Text a
parseUrlPiece

-- | Document metadata
data Document = Document
    { Document -> DocumentID
identifier :: DocumentID
    , Document -> Text
name :: Text
    , Document -> Int64
group :: GroupID
    , Document -> UTCTime
created :: UTCTime
    , Document -> UserRef
createdBy :: UserRef
    , Document -> UTCTime
lastEdited :: UTCTime
    , Document -> UserRef
lastEditedBy :: UserRef
    }
    deriving (Document -> Document -> Bool
(Document -> Document -> Bool)
-> (Document -> Document -> Bool) -> Eq Document
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Document -> Document -> Bool
== :: Document -> Document -> Bool
$c/= :: Document -> Document -> Bool
/= :: Document -> Document -> Bool
Eq, Int -> Document -> ShowS
[Document] -> ShowS
Document -> String
(Int -> Document -> ShowS)
-> (Document -> String) -> ([Document] -> ShowS) -> Show Document
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Document -> ShowS
showsPrec :: Int -> Document -> ShowS
$cshow :: Document -> String
show :: Document -> String
$cshowList :: [Document] -> ShowS
showList :: [Document] -> ShowS
Show, (forall x. Document -> Rep Document x)
-> (forall x. Rep Document x -> Document) -> Generic Document
forall x. Rep Document x -> Document
forall x. Document -> Rep Document x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Document -> Rep Document x
from :: forall x. Document -> Rep Document x
$cto :: forall x. Rep Document x -> Document
to :: forall x. Rep Document x -> Document
Generic)

instance ToJSON Document

instance FromJSON Document

instance ToSchema Document