{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}

module Facebook.Object.Page
  ( Page(..)
  , getPage
  , getPage_
  , searchPages
  ) where

import Control.Monad (mzero)
import Data.Aeson ((.:), (.:?))
import qualified Control.Monad.Trans.Resource as R
import qualified Data.Aeson as A
import Data.Text (Text)
import Data.Typeable (Typeable)

import Facebook.Graph
import Facebook.Monad
import Facebook.Types
import Facebook.Pager

-- | A Facebook page (see
-- <https://developers.facebook.com/docs/reference/api/page/>).
--
-- /NOTE:/ Does not yet support all fields. Please file an issue if
-- you need any other fields.
data Page = Page
  { Page -> Id
pageId :: Id
  , Page -> Maybe Text
pageName :: Maybe Text
  , Page -> Maybe Text
pageLink :: Maybe Text
  , Page -> Maybe Text
pageCategory :: Maybe Text
  , Page -> Maybe Bool
pageIsPublished :: Maybe Bool
  , Page -> Maybe Bool
pageCanPost :: Maybe Bool
  , Page -> Maybe Integer
pageLikes :: Maybe Integer
  , Page -> Maybe Location
pageLocation :: Maybe Location
  , Page -> Maybe Text
pagePhone :: Maybe Text
  , Page -> Maybe Integer
pageCheckins :: Maybe Integer
  , Page -> Maybe Text
pagePicture :: Maybe Text
  , Page -> Maybe Text
pageWebsite :: Maybe Text
  , Page -> Maybe Integer
pageTalkingAboutCount :: Maybe Integer
  } deriving (Page -> Page -> Bool
(Page -> Page -> Bool) -> (Page -> Page -> Bool) -> Eq Page
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Page -> Page -> Bool
$c/= :: Page -> Page -> Bool
== :: Page -> Page -> Bool
$c== :: Page -> Page -> Bool
Eq, Eq Page
Eq Page
-> (Page -> Page -> Ordering)
-> (Page -> Page -> Bool)
-> (Page -> Page -> Bool)
-> (Page -> Page -> Bool)
-> (Page -> Page -> Bool)
-> (Page -> Page -> Page)
-> (Page -> Page -> Page)
-> Ord Page
Page -> Page -> Bool
Page -> Page -> Ordering
Page -> Page -> Page
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Page -> Page -> Page
$cmin :: Page -> Page -> Page
max :: Page -> Page -> Page
$cmax :: Page -> Page -> Page
>= :: Page -> Page -> Bool
$c>= :: Page -> Page -> Bool
> :: Page -> Page -> Bool
$c> :: Page -> Page -> Bool
<= :: Page -> Page -> Bool
$c<= :: Page -> Page -> Bool
< :: Page -> Page -> Bool
$c< :: Page -> Page -> Bool
compare :: Page -> Page -> Ordering
$ccompare :: Page -> Page -> Ordering
$cp1Ord :: Eq Page
Ord, Int -> Page -> ShowS
[Page] -> ShowS
Page -> String
(Int -> Page -> ShowS)
-> (Page -> String) -> ([Page] -> ShowS) -> Show Page
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Page] -> ShowS
$cshowList :: [Page] -> ShowS
show :: Page -> String
$cshow :: Page -> String
showsPrec :: Int -> Page -> ShowS
$cshowsPrec :: Int -> Page -> ShowS
Show, ReadPrec [Page]
ReadPrec Page
Int -> ReadS Page
ReadS [Page]
(Int -> ReadS Page)
-> ReadS [Page] -> ReadPrec Page -> ReadPrec [Page] -> Read Page
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Page]
$creadListPrec :: ReadPrec [Page]
readPrec :: ReadPrec Page
$creadPrec :: ReadPrec Page
readList :: ReadS [Page]
$creadList :: ReadS [Page]
readsPrec :: Int -> ReadS Page
$creadsPrec :: Int -> ReadS Page
Read, Typeable)

instance A.FromJSON Page where
  parseJSON :: Value -> Parser Page
parseJSON (A.Object Object
v) =
    Id
-> Maybe Text
-> Maybe Text
-> Maybe Text
-> Maybe Bool
-> Maybe Bool
-> Maybe Integer
-> Maybe Location
-> Maybe Text
-> Maybe Integer
-> Maybe Text
-> Maybe Text
-> Maybe Integer
-> Page
Page (Id
 -> Maybe Text
 -> Maybe Text
 -> Maybe Text
 -> Maybe Bool
 -> Maybe Bool
 -> Maybe Integer
 -> Maybe Location
 -> Maybe Text
 -> Maybe Integer
 -> Maybe Text
 -> Maybe Text
 -> Maybe Integer
 -> Page)
-> Parser Id
-> Parser
     (Maybe Text
      -> Maybe Text
      -> Maybe Text
      -> Maybe Bool
      -> Maybe Bool
      -> Maybe Integer
      -> Maybe Location
      -> Maybe Text
      -> Maybe Integer
      -> Maybe Text
      -> Maybe Text
      -> Maybe Integer
      -> Page)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
v Object -> Key -> Parser Id
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"id" Parser
  (Maybe Text
   -> Maybe Text
   -> Maybe Text
   -> Maybe Bool
   -> Maybe Bool
   -> Maybe Integer
   -> Maybe Location
   -> Maybe Text
   -> Maybe Integer
   -> Maybe Text
   -> Maybe Text
   -> Maybe Integer
   -> Page)
-> Parser (Maybe Text)
-> Parser
     (Maybe Text
      -> Maybe Text
      -> Maybe Bool
      -> Maybe Bool
      -> Maybe Integer
      -> Maybe Location
      -> Maybe Text
      -> Maybe Integer
      -> Maybe Text
      -> Maybe Text
      -> Maybe Integer
      -> Page)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"name" Parser
  (Maybe Text
   -> Maybe Text
   -> Maybe Bool
   -> Maybe Bool
   -> Maybe Integer
   -> Maybe Location
   -> Maybe Text
   -> Maybe Integer
   -> Maybe Text
   -> Maybe Text
   -> Maybe Integer
   -> Page)
-> Parser (Maybe Text)
-> Parser
     (Maybe Text
      -> Maybe Bool
      -> Maybe Bool
      -> Maybe Integer
      -> Maybe Location
      -> Maybe Text
      -> Maybe Integer
      -> Maybe Text
      -> Maybe Text
      -> Maybe Integer
      -> Page)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"link" Parser
  (Maybe Text
   -> Maybe Bool
   -> Maybe Bool
   -> Maybe Integer
   -> Maybe Location
   -> Maybe Text
   -> Maybe Integer
   -> Maybe Text
   -> Maybe Text
   -> Maybe Integer
   -> Page)
-> Parser (Maybe Text)
-> Parser
     (Maybe Bool
      -> Maybe Bool
      -> Maybe Integer
      -> Maybe Location
      -> Maybe Text
      -> Maybe Integer
      -> Maybe Text
      -> Maybe Text
      -> Maybe Integer
      -> Page)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"category" Parser
  (Maybe Bool
   -> Maybe Bool
   -> Maybe Integer
   -> Maybe Location
   -> Maybe Text
   -> Maybe Integer
   -> Maybe Text
   -> Maybe Text
   -> Maybe Integer
   -> Page)
-> Parser (Maybe Bool)
-> Parser
     (Maybe Bool
      -> Maybe Integer
      -> Maybe Location
      -> Maybe Text
      -> Maybe Integer
      -> Maybe Text
      -> Maybe Text
      -> Maybe Integer
      -> Page)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
    Object
v Object -> Key -> Parser (Maybe Bool)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"is_published" Parser
  (Maybe Bool
   -> Maybe Integer
   -> Maybe Location
   -> Maybe Text
   -> Maybe Integer
   -> Maybe Text
   -> Maybe Text
   -> Maybe Integer
   -> Page)
-> Parser (Maybe Bool)
-> Parser
     (Maybe Integer
      -> Maybe Location
      -> Maybe Text
      -> Maybe Integer
      -> Maybe Text
      -> Maybe Text
      -> Maybe Integer
      -> Page)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
    Object
v Object -> Key -> Parser (Maybe Bool)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"can_post" Parser
  (Maybe Integer
   -> Maybe Location
   -> Maybe Text
   -> Maybe Integer
   -> Maybe Text
   -> Maybe Text
   -> Maybe Integer
   -> Page)
-> Parser (Maybe Integer)
-> Parser
     (Maybe Location
      -> Maybe Text
      -> Maybe Integer
      -> Maybe Text
      -> Maybe Text
      -> Maybe Integer
      -> Page)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
    Object
v Object -> Key -> Parser (Maybe Integer)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"likes" Parser
  (Maybe Location
   -> Maybe Text
   -> Maybe Integer
   -> Maybe Text
   -> Maybe Text
   -> Maybe Integer
   -> Page)
-> Parser (Maybe Location)
-> Parser
     (Maybe Text
      -> Maybe Integer
      -> Maybe Text
      -> Maybe Text
      -> Maybe Integer
      -> Page)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
    Object
v Object -> Key -> Parser (Maybe Location)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"location" Parser
  (Maybe Text
   -> Maybe Integer
   -> Maybe Text
   -> Maybe Text
   -> Maybe Integer
   -> Page)
-> Parser (Maybe Text)
-> Parser
     (Maybe Integer
      -> Maybe Text -> Maybe Text -> Maybe Integer -> Page)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
    Object
v Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"phone" Parser
  (Maybe Integer
   -> Maybe Text -> Maybe Text -> Maybe Integer -> Page)
-> Parser (Maybe Integer)
-> Parser (Maybe Text -> Maybe Text -> Maybe Integer -> Page)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
    Object
v Object -> Key -> Parser (Maybe Integer)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"checkin" Parser (Maybe Text -> Maybe Text -> Maybe Integer -> Page)
-> Parser (Maybe Text)
-> Parser (Maybe Text -> Maybe Integer -> Page)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
    Object
v Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"picture" Parser (Maybe Text -> Maybe Integer -> Page)
-> Parser (Maybe Text) -> Parser (Maybe Integer -> Page)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
    Object
v Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"website" Parser (Maybe Integer -> Page)
-> Parser (Maybe Integer) -> Parser Page
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*>
    Object
v Object -> Key -> Parser (Maybe Integer)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"talking_about_count"
  parseJSON Value
_ = Parser Page
forall (m :: * -> *) a. MonadPlus m => m a
mzero

-- | Get a page using its ID. The user access token is optional.
getPage
  :: (R.MonadResource m, R.MonadUnliftIO m, R.MonadThrow m)
  => Id -- ^ Page ID
  -> [Argument] -- ^ Arguments to be passed to Facebook
  -> Maybe UserAccessToken -- ^ Optional user access token
  -> FacebookT anyAuth m Page
getPage :: Id
-> [Argument] -> Maybe UserAccessToken -> FacebookT anyAuth m Page
getPage Id
id_ = Text
-> [Argument] -> Maybe UserAccessToken -> FacebookT anyAuth m Page
forall (m :: * -> *) a anyKind anyAuth.
(MonadResource m, MonadUnliftIO m, MonadThrow m, FromJSON a) =>
Text
-> [Argument]
-> Maybe (AccessToken anyKind)
-> FacebookT anyAuth m a
getObject (Text
 -> [Argument] -> Maybe UserAccessToken -> FacebookT anyAuth m Page)
-> Text
-> [Argument]
-> Maybe UserAccessToken
-> FacebookT anyAuth m Page
forall a b. (a -> b) -> a -> b
$ (Text
"/" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Id -> Text
idCode Id
id_)

-- | Get a page using its ID. The user access token is optional.
getPage_
  :: (R.MonadResource m, R.MonadUnliftIO m, R.MonadThrow m)
  => Id -- ^ Page ID
  -> [Argument] -- ^ Arguments to be passed to Facebook
  -> Maybe AppAccessToken -- ^ Optional user access token
  -> FacebookT anyAuth m Page
getPage_ :: Id
-> [Argument] -> Maybe AppAccessToken -> FacebookT anyAuth m Page
getPage_ Id
id_ = Text
-> [Argument] -> Maybe AppAccessToken -> FacebookT anyAuth m Page
forall (m :: * -> *) a anyKind anyAuth.
(MonadResource m, MonadUnliftIO m, MonadThrow m, FromJSON a) =>
Text
-> [Argument]
-> Maybe (AccessToken anyKind)
-> FacebookT anyAuth m a
getObject (Text
 -> [Argument] -> Maybe AppAccessToken -> FacebookT anyAuth m Page)
-> Text
-> [Argument]
-> Maybe AppAccessToken
-> FacebookT anyAuth m Page
forall a b. (a -> b) -> a -> b
$ Text
"/" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Id -> Text
idCode Id
id_

-- | Search pages by keyword. The user access token is optional.
searchPages
  :: (R.MonadResource m, R.MonadUnliftIO m, R.MonadThrow m)
  => Text -- ^ Keyword to search for
  -> [Argument] -- ^ Arguments to pass to Facebook
  -> Maybe UserAccessToken -- ^ Optional user access token
  -> FacebookT anyAuth m (Pager Page)
searchPages :: Text
-> [Argument]
-> Maybe UserAccessToken
-> FacebookT anyAuth m (Pager Page)
searchPages = Text
-> Text
-> [Argument]
-> Maybe UserAccessToken
-> FacebookT anyAuth m (Pager Page)
forall (m :: * -> *) a anyAuth.
(MonadResource m, MonadUnliftIO m, MonadThrow m, FromJSON a) =>
Text
-> Text
-> [Argument]
-> Maybe UserAccessToken
-> FacebookT anyAuth m (Pager a)
searchObjects Text
"page"