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

    module Facebook.Object.Checkin
      ( Checkin(..)
      , CheckinFrom(..)
      , getCheckin
      , createCheckin
      ) where
    #if __GLASGOW_HASKELL__ <= 784
    import Control.Applicative
    #endif
    import Control.Monad (mzero)
    import Data.Aeson ((.:), (.:?))
    import Data.Text (Text)
    import Data.Time (UTCTime)
    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

    -- | A Facebook check-in (see
    -- <https://developers.facebook.com/docs/reference/api/checkin/>).
    --
    -- /NOTE:/ We still don't support all fields supported by
    -- Facebook. Please fill an issue if you need access to any other
    -- fields.
    data Checkin = Checkin
      { Checkin -> Id
    checkinId :: Id
      , Checkin -> Maybe CheckinFrom
    checkinFrom :: Maybe CheckinFrom
      , Checkin -> Maybe Place
    checkinPlace :: Maybe Place
      , Checkin -> Maybe UTCTime
    checkinCreatedTime :: Maybe UTCTime
      , Checkin -> Maybe (Pager Tag)
    checkinTags :: Maybe (Pager Tag)
      , Checkin -> Maybe Text
    checkinMessage :: Maybe Text
      } deriving (Checkin -> Checkin -> Bool
    (Checkin -> Checkin -> Bool)
    -> (Checkin -> Checkin -> Bool) -> Eq Checkin
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: Checkin -> Checkin -> Bool
    $c/= :: Checkin -> Checkin -> Bool
    == :: Checkin -> Checkin -> Bool
    $c== :: Checkin -> Checkin -> Bool
    Eq, Eq Checkin
    Eq Checkin =>
    (Checkin -> Checkin -> Ordering)
    -> (Checkin -> Checkin -> Bool)
    -> (Checkin -> Checkin -> Bool)
    -> (Checkin -> Checkin -> Bool)
    -> (Checkin -> Checkin -> Bool)
    -> (Checkin -> Checkin -> Checkin)
    -> (Checkin -> Checkin -> Checkin)
    -> Ord Checkin
    Checkin -> Checkin -> Bool
    Checkin -> Checkin -> Ordering
    Checkin -> Checkin -> Checkin
    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 :: Checkin -> Checkin -> Checkin
    $cmin :: Checkin -> Checkin -> Checkin
    max :: Checkin -> Checkin -> Checkin
    $cmax :: Checkin -> Checkin -> Checkin
    >= :: Checkin -> Checkin -> Bool
    $c>= :: Checkin -> Checkin -> Bool
    > :: Checkin -> Checkin -> Bool
    $c> :: Checkin -> Checkin -> Bool
    <= :: Checkin -> Checkin -> Bool
    $c<= :: Checkin -> Checkin -> Bool
    < :: Checkin -> Checkin -> Bool
    $c< :: Checkin -> Checkin -> Bool
    compare :: Checkin -> Checkin -> Ordering
    $ccompare :: Checkin -> Checkin -> Ordering
    $cp1Ord :: Eq Checkin
    Ord, Int -> Checkin -> ShowS
    [Checkin] -> ShowS
    Checkin -> String
    (Int -> Checkin -> ShowS)
    -> (Checkin -> String) -> ([Checkin] -> ShowS) -> Show Checkin
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [Checkin] -> ShowS
    $cshowList :: [Checkin] -> ShowS
    show :: Checkin -> String
    $cshow :: Checkin -> String
    showsPrec :: Int -> Checkin -> ShowS
    $cshowsPrec :: Int -> Checkin -> ShowS
    Show, ReadPrec [Checkin]
    ReadPrec Checkin
    Int -> ReadS Checkin
    ReadS [Checkin]
    (Int -> ReadS Checkin)
    -> ReadS [Checkin]
    -> ReadPrec Checkin
    -> ReadPrec [Checkin]
    -> Read Checkin
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    readListPrec :: ReadPrec [Checkin]
    $creadListPrec :: ReadPrec [Checkin]
    readPrec :: ReadPrec Checkin
    $creadPrec :: ReadPrec Checkin
    readList :: ReadS [Checkin]
    $creadList :: ReadS [Checkin]
    readsPrec :: Int -> ReadS Checkin
    $creadsPrec :: Int -> ReadS Checkin
    Read, Typeable)

    instance A.FromJSON Checkin where
      parseJSON :: Value -> Parser Checkin
    parseJSON (A.Object v :: Object
    v) =
        Id
    -> Maybe CheckinFrom
    -> Maybe Place
    -> Maybe UTCTime
    -> Maybe (Pager Tag)
    -> Maybe Text
    -> Checkin
    Checkin (Id
     -> Maybe CheckinFrom
     -> Maybe Place
     -> Maybe UTCTime
     -> Maybe (Pager Tag)
     -> Maybe Text
     -> Checkin)
    -> Parser Id
    -> Parser
         (Maybe CheckinFrom
          -> Maybe Place
          -> Maybe UTCTime
          -> Maybe (Pager Tag)
          -> Maybe Text
          -> Checkin)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Object
    v Object -> Text -> Parser Id
    forall a. FromJSON a => Object -> Text -> Parser a
    .: "id" Parser
      (Maybe CheckinFrom
       -> Maybe Place
       -> Maybe UTCTime
       -> Maybe (Pager Tag)
       -> Maybe Text
       -> Checkin)
    -> Parser (Maybe CheckinFrom)
    -> Parser
         (Maybe Place
          -> Maybe UTCTime -> Maybe (Pager Tag) -> Maybe Text -> Checkin)
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Object
    v Object -> Text -> Parser (Maybe CheckinFrom)
    forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
    .:? "from" Parser
      (Maybe Place
       -> Maybe UTCTime -> Maybe (Pager Tag) -> Maybe Text -> Checkin)
    -> Parser (Maybe Place)
    -> Parser
         (Maybe UTCTime -> Maybe (Pager Tag) -> Maybe Text -> Checkin)
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Object
    v Object -> Text -> Parser (Maybe Place)
    forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
    .:? "place" Parser
      (Maybe UTCTime -> Maybe (Pager Tag) -> Maybe Text -> Checkin)
    -> Parser (Maybe UTCTime)
    -> Parser (Maybe (Pager Tag) -> Maybe Text -> Checkin)
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*>
        ((FbUTCTime -> UTCTime
    unFbUTCTime (FbUTCTime -> UTCTime) -> Maybe FbUTCTime -> Maybe UTCTime
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>) (Maybe FbUTCTime -> Maybe UTCTime)
    -> Parser (Maybe FbUTCTime) -> Parser (Maybe UTCTime)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Object
    v Object -> Text -> Parser (Maybe FbUTCTime)
    forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
    .:? "created_time") Parser (Maybe (Pager Tag) -> Maybe Text -> Checkin)
    -> Parser (Maybe (Pager Tag)) -> Parser (Maybe Text -> Checkin)
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*>
        Object
    v Object -> Text -> Parser (Maybe (Pager Tag))
    forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
    .:? "tags" Parser (Maybe Text -> Checkin)
    -> Parser (Maybe Text) -> Parser Checkin
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*>
        Object
    v Object -> Text -> Parser (Maybe Text)
    forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
    .:? "message"
      parseJSON _ = Parser Checkin
    forall (m :: * -> *) a. MonadPlus m => m a
    mzero

    -- | Information about the user who made the check-in.
    data CheckinFrom = CheckinFrom
      { CheckinFrom -> Id
    checkinFromId :: UserId
      , CheckinFrom -> Text
    checkinFromName :: Text
      } deriving (CheckinFrom -> CheckinFrom -> Bool
    (CheckinFrom -> CheckinFrom -> Bool)
    -> (CheckinFrom -> CheckinFrom -> Bool) -> Eq CheckinFrom
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: CheckinFrom -> CheckinFrom -> Bool
    $c/= :: CheckinFrom -> CheckinFrom -> Bool
    == :: CheckinFrom -> CheckinFrom -> Bool
    $c== :: CheckinFrom -> CheckinFrom -> Bool
    Eq, Eq CheckinFrom
    Eq CheckinFrom =>
    (CheckinFrom -> CheckinFrom -> Ordering)
    -> (CheckinFrom -> CheckinFrom -> Bool)
    -> (CheckinFrom -> CheckinFrom -> Bool)
    -> (CheckinFrom -> CheckinFrom -> Bool)
    -> (CheckinFrom -> CheckinFrom -> Bool)
    -> (CheckinFrom -> CheckinFrom -> CheckinFrom)
    -> (CheckinFrom -> CheckinFrom -> CheckinFrom)
    -> Ord CheckinFrom
    CheckinFrom -> CheckinFrom -> Bool
    CheckinFrom -> CheckinFrom -> Ordering
    CheckinFrom -> CheckinFrom -> CheckinFrom
    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 :: CheckinFrom -> CheckinFrom -> CheckinFrom
    $cmin :: CheckinFrom -> CheckinFrom -> CheckinFrom
    max :: CheckinFrom -> CheckinFrom -> CheckinFrom
    $cmax :: CheckinFrom -> CheckinFrom -> CheckinFrom
    >= :: CheckinFrom -> CheckinFrom -> Bool
    $c>= :: CheckinFrom -> CheckinFrom -> Bool
    > :: CheckinFrom -> CheckinFrom -> Bool
    $c> :: CheckinFrom -> CheckinFrom -> Bool
    <= :: CheckinFrom -> CheckinFrom -> Bool
    $c<= :: CheckinFrom -> CheckinFrom -> Bool
    < :: CheckinFrom -> CheckinFrom -> Bool
    $c< :: CheckinFrom -> CheckinFrom -> Bool
    compare :: CheckinFrom -> CheckinFrom -> Ordering
    $ccompare :: CheckinFrom -> CheckinFrom -> Ordering
    $cp1Ord :: Eq CheckinFrom
    Ord, Int -> CheckinFrom -> ShowS
    [CheckinFrom] -> ShowS
    CheckinFrom -> String
    (Int -> CheckinFrom -> ShowS)
    -> (CheckinFrom -> String)
    -> ([CheckinFrom] -> ShowS)
    -> Show CheckinFrom
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [CheckinFrom] -> ShowS
    $cshowList :: [CheckinFrom] -> ShowS
    show :: CheckinFrom -> String
    $cshow :: CheckinFrom -> String
    showsPrec :: Int -> CheckinFrom -> ShowS
    $cshowsPrec :: Int -> CheckinFrom -> ShowS
    Show, ReadPrec [CheckinFrom]
    ReadPrec CheckinFrom
    Int -> ReadS CheckinFrom
    ReadS [CheckinFrom]
    (Int -> ReadS CheckinFrom)
    -> ReadS [CheckinFrom]
    -> ReadPrec CheckinFrom
    -> ReadPrec [CheckinFrom]
    -> Read CheckinFrom
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    readListPrec :: ReadPrec [CheckinFrom]
    $creadListPrec :: ReadPrec [CheckinFrom]
    readPrec :: ReadPrec CheckinFrom
    $creadPrec :: ReadPrec CheckinFrom
    readList :: ReadS [CheckinFrom]
    $creadList :: ReadS [CheckinFrom]
    readsPrec :: Int -> ReadS CheckinFrom
    $creadsPrec :: Int -> ReadS CheckinFrom
    Read, Typeable)

    instance A.FromJSON CheckinFrom where
      parseJSON :: Value -> Parser CheckinFrom
    parseJSON (A.Object v :: Object
    v) = Id -> Text -> CheckinFrom
    CheckinFrom (Id -> Text -> CheckinFrom)
    -> Parser Id -> Parser (Text -> CheckinFrom)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Object
    v Object -> Text -> Parser Id
    forall a. FromJSON a => Object -> Text -> Parser a
    .: "id" Parser (Text -> CheckinFrom) -> Parser Text -> Parser CheckinFrom
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Object
    v Object -> Text -> Parser Text
    forall a. FromJSON a => Object -> Text -> Parser a
    .: "name"
      parseJSON _ = Parser CheckinFrom
    forall (m :: * -> *) a. MonadPlus m => m a
    mzero

    -- | Get a checkin from its ID.  The user access token is
    -- optional, but when provided more information can be returned
    -- back by Facebook.
    getCheckin
      :: (R.MonadResource m, R.MonadUnliftIO m, R.MonadThrow m)
      => Id -- ^ Checkin ID.
      -> [Argument] -- ^ Arguments to be passed to Facebook.
      -> Maybe UserAccessToken -- ^ Optional user access token.
      -> FacebookT anyAuth m Checkin
    getCheckin :: Id
    -> [Argument]
    -> Maybe UserAccessToken
    -> FacebookT anyAuth m Checkin
    getCheckin id_ :: Id
    id_ query :: [Argument]
    query mtoken :: Maybe UserAccessToken
    mtoken = Text
    -> [Argument]
    -> Maybe UserAccessToken
    -> FacebookT anyAuth m Checkin
    forall (m :: * -> *) a anyKind anyAuth.
    (MonadResource m, MonadUnliftIO m, MonadThrow m, FromJSON a) =>
    Text
    -> [Argument]
    -> Maybe (AccessToken anyKind)
    -> FacebookT anyAuth m a
    getObject ("/" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Id -> Text
    idCode Id
    id_) [Argument]
    query Maybe UserAccessToken
    mtoken

    -- | Creates a 'check-in' and returns its ID. Place and
    -- coordinates are both required by Facebook.
    createCheckin
      :: (R.MonadResource m, R.MonadUnliftIO m, R.MonadThrow m)
      => Id -- ^ Place ID.
      -> GeoCoordinates -- ^ Coordinates.
      -> [Argument] -- ^ Other arguments of the action.
      -> UserAccessToken -- ^ Required user access token.
      -> FacebookT Auth m Id
    createCheckin :: Id
    -> GeoCoordinates
    -> [Argument]
    -> UserAccessToken
    -> FacebookT Auth m Id
    createCheckin pid :: Id
    pid coords :: GeoCoordinates
    coords args :: [Argument]
    args usertoken :: UserAccessToken
    usertoken = do
      let body :: [Argument]
    body = ("place" ByteString -> Id -> Argument
    forall a. SimpleType a => ByteString -> a -> Argument
    #= Id
    pid) Argument -> [Argument] -> [Argument]
    forall a. a -> [a] -> [a]
    : ("coordinates" ByteString -> GeoCoordinates -> Argument
    forall a. SimpleType a => ByteString -> a -> Argument
    #= GeoCoordinates
    coords) Argument -> [Argument] -> [Argument]
    forall a. a -> [a] -> [a]
    : [Argument]
    args
      Text -> [Argument] -> UserAccessToken -> 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 "me/checkins" [Argument]
    body UserAccessToken
    usertoken