{-# LANGUAGE DeriveDataTypeable, FlexibleContexts, OverloadedStrings #-}
module Facebook.Object.FriendList
    ( FriendList(..)
    , FriendListType(..)
    , getUserFriendLists
    , getFriendListMembers
    ) where

import Control.Applicative
import Control.Monad (mzero)
import Control.Monad.Trans.Control (MonadBaseControl)
import Data.Aeson ((.:))
import Data.Text (Text)
import Data.Typeable (Typeable)

import qualified Control.Monad.Trans.Resource as R
import qualified Data.Aeson as A


import Facebook.Types
import Facebook.Monad
import Facebook.Graph
import Facebook.Pager
import Facebook.Object.User

-- | A friend list for a 'User'.
data FriendList =
    FriendList { friendListId    :: Id
               , friendListName  :: Text
               , friendListType  :: FriendListType
               }
    deriving (Eq, Ord, Show, Read, Typeable)

instance A.FromJSON FriendList where
    parseJSON (A.Object v) =
      FriendList <$> v .: "id"
                 <*> v .: "name"
                 <*> v .: "list_type"
    parseJSON _ = mzero

data FriendListType = CloseFriendsList | AcquaintancesList | RestrictedList
    | UserCreatedList | EducationList | WorkList | CurrentCityList | FamilyList
    deriving (Eq, Ord, Show, Read, Enum, Typeable)

instance A.FromJSON FriendListType where
    parseJSON (A.String "close_friends") = return CloseFriendsList
    parseJSON (A.String "acquaintances") = return AcquaintancesList
    parseJSON (A.String "restricted")    = return RestrictedList
    parseJSON (A.String "user_created")  = return UserCreatedList
    parseJSON (A.String "education")     = return EducationList
    parseJSON (A.String "work")          = return WorkList
    parseJSON (A.String "current_city")  = return CurrentCityList
    parseJSON (A.String "family")        = return FamilyList
    parseJSON _                          = mzero

instance A.ToJSON FriendListType where
    toJSON = A.toJSON . toText
        where
          toText :: FriendListType -> Text
          toText CloseFriendsList  = "close_friends"
          toText AcquaintancesList = "aquaintances"
          toText RestrictedList    = "restricted"
          toText UserCreatedList   = "user_created"
          toText EducationList     = "education"
          toText WorkList          = "work"
          toText CurrentCityList   = "current_city"
          toText FamilyList        = "family"

-- close_friends, acquaintances, restricted, user_created, education, work, current_city, family

-- | Get the friend lists of the given user.
getUserFriendLists ::
     (R.MonadResource m, MonadBaseControl IO m) =>
     UserId          -- ^ User ID or @\"me\"@.
  -> [Argument]      -- ^ Arguments to be passed to Facebook.
  -> UserAccessToken -- ^ User access token.
  -> FacebookT anyAuth m (Pager FriendList)
getUserFriendLists id_ query token =
  getObject ("/" <> idCode id_ <> "/friendlists") query (Just token)

-- | Get the members of a friend list.
getFriendListMembers ::
     (R.MonadResource m, MonadBaseControl IO m) =>
     Id              -- ^ List ID.
  -> [Argument]      -- ^ Arguments to be passed to Facebook.
  -> UserAccessToken -- ^ User access token.
  -> FacebookT anyAuth m (Pager Friend)
getFriendListMembers id_ query token =
  getObject ("/" <> idCode id_ <> "/members") query (Just token)