    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE CPP #-}
    {-# LANGUAGE FlexibleInstances #-}
    {-# LANGUAGE TemplateHaskell #-}
    {-# LANGUAGE EmptyDataDecls #-}

    module Web.Twitter.Conduit.Status
           (
           -- * Timelines
             StatusesMentionsTimeline
           , mentionsTimeline
           , StatusesUserTimeline
           , userTimeline
           , StatusesHomeTimeline
           , homeTimeline
           , StatusesRetweetsOfMe
           , retweetsOfMe
           -- * Tweets
           , StatusesRetweetsId
           , retweetsId
           , StatusesShowId
           , showId
           , StatusesDestroyId
           , destroyId
           , StatusesUpdate
           , update
           , StatusesRetweetId
           , retweetId
           , MediaData (..)
           , StatusesUpdateWithMedia
           , updateWithMedia
           -- , oembed
           -- , retweetersIds
           , StatusesLookup
           , lookup
           ) where

    import Prelude hiding ( lookup )
    import Web.Twitter.Conduit.Base
    import Web.Twitter.Conduit.Request
    import Web.Twitter.Conduit.Parameters
    import Web.Twitter.Conduit.Parameters.TH
    import Web.Twitter.Types

    import qualified Data.Text as T
    import Network.HTTP.Client.MultipartFormData
    import Data.Default

    -- $setup
    -- >>> :set -XOverloadedStrings
    -- >>> import Control.Lens

    -- * Timelines

    data StatusesMentionsTimeline
    -- | Returns query data asks the most recent mentions for the authenticating user.
    --
    -- You can perform a query using 'call':
    --
    -- @
    -- res <- 'call' 'mentionsTimeline'
    -- @
    --
    -- >>> mentionsTimeline
    -- APIRequestGet "https://api.twitter.com/1.1/statuses/mentions_timeline.json" []
    mentionsTimeline :: APIRequest StatusesMentionsTimeline [Status]
    mentionsTimeline = APIRequestGet (endpoint ++ "statuses/mentions_timeline.json") def
    deriveHasParamInstances ''StatusesMentionsTimeline
        [ "count"
        , "since_id"
        , "max_id"
        , "trim_user"
        , "contributor_details"
        , "include_entities"
        ]

    data StatusesUserTimeline
    -- | Returns query data asks a collection of the most recent Tweets posted by the user indicated by the screen_name or user_id parameters.
    --
    -- You can perform a search query using 'call':
    --
    -- @
    -- res <- 'call' $ 'userTimeline' ('ScreenNameParam' \"thimura\")
    -- @
    --
    -- >>> userTimeline (ScreenNameParam "thimura")
    -- APIRequestGet "https://api.twitter.com/1.1/statuses/user_timeline.json" [("screen_name","thimura")]
    -- >>> userTimeline (ScreenNameParam "thimura") & includeRts ?~ True & count ?~ 200
    -- APIRequestGet "https://api.twitter.com/1.1/statuses/user_timeline.json" [("count","200"),("include_rts","true"),("screen_name","thimura")]
    userTimeline :: UserParam -> APIRequest StatusesUserTimeline [Status]
    userTimeline q = APIRequestGet (endpoint ++ "statuses/user_timeline.json") (mkUserParam q)
    deriveHasParamInstances ''StatusesUserTimeline
        [ "count"
        , "since_id"
        , "max_id"
        , "trim_user"
        , "exclude_replies"
        , "contributor_details"
        , "include_rts"
        ]

    data StatusesHomeTimeline
    -- | Returns query data asks a collection of the most recentTweets and retweets posted by the authenticating user and the users they follow.
    --
    -- You can perform a search query using 'call':
    --
    -- @
    -- res <- 'call' 'homeTimeline'
    -- @
    --
    -- >>> homeTimeline
    -- APIRequestGet "https://api.twitter.com/1.1/statuses/home_timeline.json" []
    -- >>> homeTimeline & count ?~ 200
    -- APIRequestGet "https://api.twitter.com/1.1/statuses/home_timeline.json" [("count","200")]
    homeTimeline :: APIRequest StatusesHomeTimeline [Status]
    homeTimeline = APIRequestGet (endpoint ++ "statuses/home_timeline.json") def
    deriveHasParamInstances ''StatusesHomeTimeline
        [ "count"
        , "since_id"
        , "max_id"
        , "trim_user"
        , "exclude_replies"
        , "contributor_details"
        , "include_entities"
        ]

    data StatusesRetweetsOfMe
    -- | Returns query data asks the most recent tweets authored by the authenticating user that have been retweeted by others.
    --
    -- You can perform a search query using 'call':
    --
    -- @
    -- res <- 'call' 'retweetsOfMe'
    -- @
    --
    -- >>> retweetsOfMe
    -- APIRequestGet "https://api.twitter.com/1.1/statuses/retweets_of_me.json" []
    -- >>> retweetsOfMe & count ?~ 100
    -- APIRequestGet "https://api.twitter.com/1.1/statuses/retweets_of_me.json" [("count","100")]
    retweetsOfMe :: APIRequest StatusesRetweetsOfMe [Status]
    retweetsOfMe = APIRequestGet (endpoint ++ "statuses/retweets_of_me.json") def
    deriveHasParamInstances ''StatusesRetweetsOfMe
        [ "count"
        , "since_id"
        , "max_id"
        , "trim_user"
        , "include_entities"
        , "include_user_entities"
        ]

    -- * Tweets

    data StatusesRetweetsId
    -- | Returns query data that asks for the most recent retweets of the specified tweet
    --
    -- You can perform a search query using 'call':
    --
    -- @
    -- res <- 'call' twInfo mgr '$' 'retweetsId' 1234567890
    -- @
    --
    -- >>> retweetsId 1234567890
    -- APIRequestGet "https://api.twitter.com/1.1/statuses/retweets/1234567890.json" []
    -- >>> retweetsId 1234567890 & count ?~ 100
    -- APIRequestGet "https://api.twitter.com/1.1/statuses/retweets/1234567890.json" [("count","100")]
    retweetsId :: StatusId -> APIRequest StatusesRetweetsId [RetweetedStatus]
    retweetsId status_id = APIRequestGet uri def
      where uri = endpoint ++ "statuses/retweets/" ++ show status_id ++ ".json"
    deriveHasParamInstances ''StatusesRetweetsId
        [ "count"
        , "trim_user"
        ]

    data StatusesShowId
    -- | Returns query data asks a single Tweet, specified by the id parameter.
    --
    -- You can perform a search query using 'call':
    --
    -- @
    -- res <- 'call' twInfo mgr '$' 'showId' 1234567890
    -- @
    --
    -- >>> showId 1234567890
    -- APIRequestGet "https://api.twitter.com/1.1/statuses/show/1234567890.json" []
    -- >>> showId 1234567890 & includeMyRetweet ?~ True
    -- APIRequestGet "https://api.twitter.com/1.1/statuses/show/1234567890.json" [("include_my_retweet","true")]
    showId :: StatusId -> APIRequest StatusesShowId Status
    showId status_id = APIRequestGet uri def
      where uri = endpoint ++ "statuses/show/" ++ show status_id ++ ".json"
    deriveHasParamInstances ''StatusesShowId
        [ "trim_user"
        , "include_my_retweet"
        , "include_entities"
        , "include_ext_alt_text"
        ]

    data StatusesDestroyId
    -- | Returns post data which destroys the status specified by the require ID parameter.
    --
    -- You can perform a search query using 'call':
    --
    -- @
    -- res <- 'call' twInfo mgr '$' 'destroyId' 1234567890
    -- @
    --
    -- >>> destroyId 1234567890
    -- APIRequestPost "https://api.twitter.com/1.1/statuses/destroy/1234567890.json" []
    destroyId :: StatusId -> APIRequest StatusesDestroyId Status
    destroyId status_id = APIRequestPost uri def
      where uri = endpoint ++ "statuses/destroy/" ++ show status_id ++ ".json"
    deriveHasParamInstances ''StatusesDestroyId
        [ "trim_user"
        ]

    data StatusesUpdate
    -- | Returns post data which updates the authenticating user's current status.
    -- To upload an image to accompany the tweet, use 'updateWithMedia'.
    --
    -- You can perform a search query using 'call':
    --
    -- @
    -- res <- 'call' twInfo mgr '$' 'update' \"Hello World\"
    -- @
    --
    -- >>> update "Hello World"
    -- APIRequestPost "https://api.twitter.com/1.1/statuses/update.json" [("status","Hello World")]
    -- >>> update "Hello World" & inReplyToStatusId ?~ 1234567890
    -- APIRequestPost "https://api.twitter.com/1.1/statuses/update.json" [("in_reply_to_status_id","1234567890"),("status","Hello World")]
    update :: T.Text -> APIRequest StatusesUpdate Status
    update status = APIRequestPost uri [("status", PVString status)]
      where uri = endpoint ++ "statuses/update.json"
    deriveHasParamInstances ''StatusesUpdate
        [ "in_reply_to_status_id"
        -- , "lat_long"
        -- , "place_id"
        , "display_coordinates"
        , "trim_user"
        , "media_ids"
        ]

    data StatusesRetweetId
    -- | Returns post data which retweets a tweet, specified by ID.
    --
    -- You can perform a search query using 'call':
    --
    -- @
    -- res <- 'call' twInfo mgr '$' 'retweetId' 1234567890
    -- @
    --
    -- >>> retweetId 1234567890
    -- APIRequestPost "https://api.twitter.com/1.1/statuses/retweet/1234567890.json" []
    retweetId :: StatusId -> APIRequest StatusesRetweetId RetweetedStatus
    retweetId status_id = APIRequestPost uri def
      where uri = endpoint ++ "statuses/retweet/" ++ show status_id ++ ".json"
    deriveHasParamInstances ''StatusesRetweetId
        [ "trim_user"
        ]

    data StatusesUpdateWithMedia
    -- | Returns post data which updates the authenticating user's current status and attaches media for upload.
    --
    -- You can perform a search query using 'call':
    --
    -- @
    -- res <- 'call' twInfo mgr '$' 'updateWithMedia' \"Hello World\" ('MediaFromFile' \"/home/thimura/test.jpeg\")
    -- @
    --
    -- >>> updateWithMedia "Hello World" (MediaFromFile "/home/fuga/test.jpeg")
    -- APIRequestPostMultipart "https://api.twitter.com/1.1/statuses/update_with_media.json" [("status","Hello World")]
    updateWithMedia :: T.Text
                    -> MediaData
                    -> APIRequest StatusesUpdateWithMedia Status
    updateWithMedia tweet mediaData =
        APIRequestPostMultipart uri [("status", PVString tweet)] [mediaBody mediaData]
      where
        uri = endpoint ++ "statuses/update_with_media.json"
        mediaBody (MediaFromFile fp) = partFileSource "media[]" fp
        mediaBody (MediaRequestBody filename filebody) = partFileRequestBody "media[]" filename filebody
    deriveHasParamInstances ''StatusesUpdateWithMedia
        [ "possibly_sensitive"
        , "in_reply_to_status_id"
        -- , "lat_long"
        -- , "place_id"
        , "display_coordinates"
        ]

    data StatusesLookup
    -- | Returns fully-hydrated tweet objects for up to 100 tweets per request, as specified by comma-separated values passed to the id parameter.
    --
    -- You can perform a request using 'call':
    --
    -- @
    -- res <- 'call' twInfo mgr '$' 'lookup' [20, 432656548536401920]
    -- @
    --
    -- >>> lookup [10]
    -- APIRequestGet "https://api.twitter.com/1.1/statuses/lookup.json" [("id","10")]
    -- >>> lookup [10, 432656548536401920]
    -- APIRequestGet "https://api.twitter.com/1.1/statuses/lookup.json" [("id","10,432656548536401920")]
    -- >>> lookup [10, 432656548536401920] & includeEntities ?~ True
    -- APIRequestGet "https://api.twitter.com/1.1/statuses/lookup.json" [("include_entities","true"),("id","10,432656548536401920")]
    lookup :: [StatusId] -> APIRequest StatusesLookup [Status]
    lookup ids = APIRequestGet (endpoint ++ "statuses/lookup.json") [("id", PVIntegerArray ids)]
    deriveHasParamInstances ''StatusesLookup
        [ "include_entities"
        , "trim_user"
        , "map"
        ]