content: {-# LANGUAGE OverloadedStrings, TemplateHaskell #-}
  module Web.Slack.Types.User where
  
  import Control.Applicative
  import Data.Aeson
  import Data.Aeson.Types
  import Data.Maybe (fromMaybe)
  import Data.Text (Text)
  import Control.Lens.TH
  
  import Web.Slack.Types.Id
  import Web.Slack.Types.Base
  
  import Prelude
  
  
  data User = User
            { _userId         :: UserId
            , _userName       :: Text
            , _userDeleted    :: Bool
            , _userColor      :: Text
            , _userProfile    :: Profile
            , _userPermission :: Permissions
            , _userHasFiles   :: Bool
            , _userTimezone   :: Timezone
            } deriving (Show)
  
  instance FromJSON User where
    parseJSON = withObject "User" (\o -> User <$> o .: "id" <*> o .: "name" <*> o .: "deleted"
                                          <*> (o .:? "color" .!= "000000")
                                          <*> o .: "profile" <*> (parseJSON (Object o) :: Parser Permissions)
                                          <*> fmap (fromMaybe False) (o .:? "has_files")
                                          <*> ((return $ fromMaybe defaultTimezone (parseMaybe parseJSON (Object o))) :: Parser Timezone))
  
  defaultTimezone :: Timezone
  defaultTimezone = Timezone Nothing "Pacific Standard Time" (-28800)
  
  
  instance FromJSON Permissions where
    parseJSON = withObject "Permissions" (\o -> let v x = (o .:? x .!= False) in
                                          Permissions <$> v "is_admin" <*> v "is_owner"
                                            <*> v "is_primary_owner" <*> v "is_restricted"
                                            <*> v "is_ultra_restricted" <*> v "is_bot")
  
  data Timezone = Timezone
                { _timezoneDesc   :: Maybe Text
                , _timezoneLabel  :: Text
                , _timezoneOffset :: Int
                } deriving Show
  
  instance FromJSON Timezone where
    parseJSON = withObject "timezone" (\o -> Timezone <$> o .:? "tz" <*> o .: "tz_label" <*> o .: "tz_offset")
  
  data Permissions = Permissions
                   { _isAdmin           :: Bool
                   , _isOwner           :: Bool
                   , _isPrimaryOwner    :: Bool
                   , _isRestricted      :: Bool
                   , _isUltraRestricted :: Bool
                   , _isBot             :: Bool
                   } deriving (Show)
  
  data Profile = Profile
               { _profileFirstName          :: Maybe Text
               , _profileLastName           :: Maybe Text
               , _profileRealName           :: Maybe Text
               , _profileRealNameNormalized :: Maybe Text
               , _profileTitle              :: Maybe Text
               , _progileEmail              :: Maybe Text
               , _profileSkype              :: Maybe Text
               , _profilePhone              :: Maybe Text
               , _profileImage24            :: URL
               , _profileImage32            :: URL
               , _profileImage48            :: URL
               , _profileImage72            :: URL
               , _profileImage192           :: URL
               } deriving (Show)
  
  makeLenses ''Profile
  makeLenses ''Permissions
  makeLenses ''Timezone
  makeLenses ''User
  
  instance FromJSON Profile where
    parseJSON = withObject "Profile"
                  (\o -> let v = (o .:)
                             vm = (o .:?) in
                    Profile <$> vm "first_name" <*> vm "last_name" <*> vm "real_name"
                            <*> vm "real_name_normalized" <*> vm "title" <*> vm "email"
                            <*> vm "skype" <*> vm "phone" <*> v "image_24" <*> v "image_32"
                            <*> v "image_48" <*> v "image_72" <*> v "image_192")
  
  type Username = Text
  