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

module Facebook.Object.Action
  ( createAction
  , Action(..)
  ) where

import Control.Arrow (first)
import Control.Monad.IO.Class
import Data.Function (on)
import Data.String (IsString(..))
import Data.Text (Text)

import qualified Control.Monad.Trans.Resource as R

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

-- | Creates an Open Graph action on the user's timeline. Returns
-- the 'Id' of the newly created action.  For example:
--
-- > now <- liftIO getCurrentTime
-- > createAction "cook"
-- >              [ "recipe" #= "http://example.com/cookie.html"
-- >              , "when"   #= now ]
-- >              token
createAction
  :: (R.MonadResource m, R.MonadUnliftIO m, R.MonadThrow m, MonadIO m)
  => Action -- ^ Action kind to be created.
  -> [Argument] -- ^ Arguments of the action.
  -> Maybe AppAccessToken
     -- ^ Optional app access token (optional with
     -- respect to this library, since you can't make
     -- this mandatory by changing the settings of
     -- your action on Facebook).
  -> UserAccessToken -- ^ Required user access token.
  -> FacebookT Auth m Id
createAction :: Action
-> [Argument]
-> Maybe AppAccessToken
-> UserAccessToken
-> FacebookT Auth m Id
createAction (Action Text
action) [Argument]
query Maybe AppAccessToken
mapptoken UserAccessToken
usertoken = do
  Credentials
creds <- FacebookT Auth m Credentials
forall (m :: * -> *).
(Monad m, MonadIO m) =>
FacebookT Auth m Credentials
getCreds
  let post
        :: (R.MonadResource m, R.MonadUnliftIO m, R.MonadThrow m)
        => Text -> AccessToken anyKind -> FacebookT Auth m Id
      post :: Text -> AccessToken anyKind -> FacebookT Auth m Id
post Text
prepath = Text -> [Argument] -> AccessToken anyKind -> FacebookT Auth m Id
forall (m :: * -> *) a anyKind.
(MonadResource m, MonadUnliftIO m, MonadThrow m, FromJSON a) =>
Text -> [Argument] -> AccessToken anyKind -> FacebookT Auth m a
postObject (Text
prepath Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Credentials -> Text
appName Credentials
creds Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
":" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
action) [Argument]
query
  case Maybe AppAccessToken
mapptoken of
    Maybe AppAccessToken
Nothing -> Text -> UserAccessToken -> FacebookT Auth m Id
forall (m :: * -> *) anyKind.
(MonadResource m, MonadUnliftIO m, MonadThrow m) =>
Text -> AccessToken anyKind -> FacebookT Auth m Id
post Text
"/me/" UserAccessToken
usertoken
    Just AppAccessToken
apptoken -> Text -> AppAccessToken -> FacebookT Auth m Id
forall (m :: * -> *) anyKind.
(MonadResource m, MonadUnliftIO m, MonadThrow m) =>
Text -> AccessToken anyKind -> FacebookT Auth m Id
post (Text
"/" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Id -> Text
idCode (UserAccessToken -> Id
accessTokenUserId UserAccessToken
usertoken) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"/") AppAccessToken
apptoken

-- | An action of your app.  Please refer to Facebook's
-- documentation at
-- <https://developers.facebook.com/docs/opengraph/keyconcepts/#actions-objects>
-- to see how you can create actions.
--
-- This is a @newtype@ of 'Text' that supports only 'IsString'.
-- This means that to create an 'Action' you should use the
-- @OverloadedStrings@ language extension.  For example,
--
-- > {-# LANGUAGE OverloadedStrings #-}
-- >
-- > foo token = do
-- >   ...
-- >   createAction "cook" [...] token
newtype Action = Action
  { Action -> Text
unAction :: Text
  }

instance Show Action where
  show :: Action -> String
show = Text -> String
forall a. Show a => a -> String
show (Text -> String) -> (Action -> Text) -> Action -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Action -> Text
unAction

-- | Since 0.7.1
instance Eq Action where
  == :: Action -> Action -> Bool
(==) = Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
(==) (Text -> Text -> Bool)
-> (Action -> Text) -> Action -> Action -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Action -> Text
unAction
  /= :: Action -> Action -> Bool
(/=) = Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
(/=) (Text -> Text -> Bool)
-> (Action -> Text) -> Action -> Action -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Action -> Text
unAction

-- | Since 0.7.1
instance Ord Action where
  compare :: Action -> Action -> Ordering
compare = Text -> Text -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Text -> Text -> Ordering)
-> (Action -> Text) -> Action -> Action -> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Action -> Text
unAction
  <= :: Action -> Action -> Bool
(<=) = Text -> Text -> Bool
forall a. Ord a => a -> a -> Bool
(<=) (Text -> Text -> Bool)
-> (Action -> Text) -> Action -> Action -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Action -> Text
unAction
  < :: Action -> Action -> Bool
(<) = Text -> Text -> Bool
forall a. Ord a => a -> a -> Bool
(<) (Text -> Text -> Bool)
-> (Action -> Text) -> Action -> Action -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Action -> Text
unAction
  >= :: Action -> Action -> Bool
(>=) = Text -> Text -> Bool
forall a. Ord a => a -> a -> Bool
(>=) (Text -> Text -> Bool)
-> (Action -> Text) -> Action -> Action -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Action -> Text
unAction
  > :: Action -> Action -> Bool
(>) = Text -> Text -> Bool
forall a. Ord a => a -> a -> Bool
(>) (Text -> Text -> Bool)
-> (Action -> Text) -> Action -> Action -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Action -> Text
unAction

-- | Since 0.7.1
instance Read Action where
  readsPrec :: Int -> ReadS Action
readsPrec = (((Text, String) -> (Action, String))
-> [(Text, String)] -> [(Action, String)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Text -> Action) -> (Text, String) -> (Action, String)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first Text -> Action
Action) ([(Text, String)] -> [(Action, String)])
-> (String -> [(Text, String)]) -> ReadS Action
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((String -> [(Text, String)]) -> ReadS Action)
-> (Int -> String -> [(Text, String)]) -> Int -> ReadS Action
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String -> [(Text, String)]
forall a. Read a => Int -> ReadS a
readsPrec

instance IsString Action where
  fromString :: String -> Action
fromString = Text -> Action
Action (Text -> Action) -> (String -> Text) -> String -> Action
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
forall a. IsString a => String -> a
fromString