# -*- coding: UTF-8 -*-
#    This file is part of arena.
#
#    arena is free software: you can redistribute it and/or modify it
#    under the terms of the GNU General Public License as published by the
#    Free Software Foundation; either version 3 of the License or, at your
#    option, any later version.
#
#    arena is distributed in the hope that it will be useful, but
#    WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABLITY
#    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
#    License for more details.
#
#    You should have received a copy of the GNU General Public License along
#    with arena.  If not, see <http://www.gnu.org/licenses/>.

## @file
#  This file customizes ASubscribedUser for use with the various arena
#  engines.

from Plugins.User.SubscribedUsers import ASubscribedUser
from Plugins.User.Subscriptions import Right, ASubscriptionError
from Local.Configuration import Site
from Plugins.Session.Arena.Sessions import asUserName
from Library.String.Utilities import Time
import os.path, sys

## The pseudo-channel used to grant group rights to all public channels
auAllPublicChannels = "$site/channels/public"
## The pseudo-channel used to grant group rights to all private channels
auAllPrivateChannels = "$site/channels/private"

## This class customizes the ASubscribedUser class for use with the
#  various arena engines.
class AnArenaUser(ASubscribedUser):
    ## Constructor
    #
    #  In addition to the parameters expected by ASubscribedUser.__init__(),
    #  this routine expects \p params to contain the following items:
    #  - \p ContentProvider -- A reference to the content provider that has 
    #                          requested the user record.
    def __init__(Self, fieldsValues=None, **params):
        params.update(
            category=Site.Users.category,
            subscriptionsCategory=Site.Subscriptions.category,
            groupCategory=Site.Groups.category
        )
        
        ASubscribedUser.__init__(Self, fieldsValues, **params)
        
        if "ContentProvider" in Self._params:
            Self._ContentProvider = Self._params["ContentProvider"]
            del Self._params["ContentProvider"]
            
            Self._Channel = Self._ContentProvider.Channel()

    ## Initializer
    def init(Self):
        result = ASubscribedUser.init(Self)

        if result:
            # Establish private attributes
            # The content provider requesting the user record
            Self._ContentProvider = None
            # The channel displayed to the user
            Self._Channel = None
            # The session used by the user
            Self._Session = None
            # The number of posts authored by the user
            Self._postsAuthored = None
            # The number of posts edited by the user
            Self._postsEdited = None

    ## Fetch the user from the data source.
    def fetch(Self, userName):
        ASubscribedUser.fetch(Self, userName)     
        
        # Update the last visited timestamp for the user
        Self["lastVisit"] = Time.now()      
    
    ## Determine whether or not the user has the specified right for the
    #  specified channel.
    def has(Self, thisRight, thisChannel):
        # Check first to see if the right to this channel is explicitly granted
        result = ASubscribedUser.has(Self, thisRight, thisChannel)
        
        # If not, check to see if a blanket subscription is given
        if (result == False) and (thisChannel == Self._Channel.name()):
            if Self._Channel["public"] == "n":
                result = ASubscribedUser.has(Self, thisRight, 
                    auAllPrivateChannels)
                    
            else:
                result = ASubscribedUser.has(Self, thisRight,
                    auAllPublicChannels)
                    
        return result
              
    # Properties ---------------------------------------------------------------           
    ## Retrieve the content provider that is providing content to the user
    def ContentProvider(Self):
        return Self._ContentProvider
        
    ## Retrieve the channel being viewed by the user
    def Channel(Self):
        return Self._Channel
        
    ## Retrieve the number of posts authored by the user
    def postsAuthored(Self):
        if Self._postsAuthored is None:
            Self._postsAuthored = Self._Source.count(Site.Posts.category,
                criteria = [
                    ("{field:author} = {}", Self.name())
                ]
            )
            
        return Self._postsAuthored
        
    ## Retrieve the number of posts edited by the user
    def postsEdited(Self):
        if Self._postsEdited is None:
            Self._postsEdited = Self._Source.count(Site.Posts.category,
                criteria = [
                    ("{field:editor} = {}", Self.name())
                ]
            )
            
        return Self._postsEdited          
