{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards   #-}

-- |This module contains the implemented JSON resource for groups as specified on
--  https://developers.google.com/admin-sdk/directory/v1/reference/groups
--  As well as the JSON resource for group members as specified on
--  https://developers.google.com/admin-sdk/directory/v1/reference/members
module Google.AdminSDK.Groups.Types where

import Control.Monad (mzero)
import           Control.Applicative ((<$>), (<*>))
import           Data.Aeson
import           Data.Text           (Text)

data Group = Group {
    -- |The unique ID of a group. A group id can be used as a group request URI's groupKey
      groupId            :: Maybe Text
    -- |The group's email address. If your account has multiple domains,
    --  select the appropriate domain for the email address. The email must be unique.
    , email              :: Text
    -- |The group's name. For a name's character usage rules, see the administration help center.
    , name               :: Text
    -- |An extended description to help users determine the purpose of a group
    , description        :: Maybe Text
    -- |Value is true if this group was created by an administrator rather than a user.
    , adminCreated       :: Bool
    -- |List of a group's alias email addresses
    , aliases            :: [Text]
    -- |List of the group's non-editable alias email addresses that are outside of the account's
    --  primary domain or subdomains. Read-only (will be ignored in POST and PUT requests)
    , nonEditableAliases :: [Text]
}

instance ToJSON Group where
    toJSON Group{..} = object [
          "id"      .= toJSON groupId
        , "email"   .= toJSON email
        , "name"    .= toJSON name
        , "description"  .= toJSON description
        , "adminCreated" .= toJSON adminCreated
        , "aliases"      .= toJSON aliases
        , "nonEditableAliases" .= toJSON nonEditableAliases
        ]

instance FromJSON Group where
    parseJSON (Object o) = Group <$> o .:? "id"
                                 <*> o .: "email"
                                 <*> o .: "name"
                                 <*> o .:? "description"
                                 <*> o .: "adminCreated"
                                 <*> o .: "aliases"
                                 <*> o .: "nonEditableAliases"
    parseJSON _ = mzero

data Member = Member {
    -- |The unique ID of the group member. A member id can be used as a member
    --  request URI's memberKey.
      memberId :: Maybe Text
    -- |The member's email address. A member can be a user or another group.
    --  This property is required when adding a member to a group.
    , memberEmail :: Text
    -- |The member's role in a group. See 'Role'
    , role :: Role
    -- |The type of group member. See 'MemberType'
    , memberType :: MemberType
}

data Role
    -- |This role can send messages to the group, add or remove members, change member roles,
    --  change group's settings, and delete the group. An OWNER does not need to be a member
    --  of the group. A group can have more than one OWNER.
    = OWNER
    -- |A MANAGER role can do everything done by an OWNER role except make a member an OWNER
    --  or delete the group. A group can have multiple MANAGER members.
    | MANAGER
    -- |This role can subscribe to a group, view discussion archives,
    --  and view the group's membership list.
    | MEMBER

data MemberType
    -- |The member is another group.
    = UserMember
    -- |The member is a user.
    | GroupMember

instance ToJSON Role where
    toJSON OWNER = "OWNER"
    toJSON MANAGER = "MANAGER"
    toJSON MEMBER = "MEMBER"

instance ToJSON MemberType where
    toJSON UserMember = "MEMBER"
    toJSON GroupMember = "GROUP"

instance ToJSON Member where
    toJSON Member{..} = object [
          "id" .= toJSON memberId
        , "email" .= toJSON memberEmail
        , "role" .= toJSON role
        , "memberType" .= toJSON memberType
        ]

instance FromJSON Role where
    parseJSON (String t) = return $ case t of
        "OWNER" -> OWNER
        "MANAGER" -> MANAGER
        "MEMBER" -> MEMBER
    parseJSON _ = mzero

instance FromJSON MemberType where
    parseJSON (String t) = return $ case t of
        "MEMBER" -> UserMember
        "GROUP"  -> GroupMember
    parseJSON _ = mzero
