# -*- coding: utf-8 -*-
##
## feeder.py
## Login : David Rousselie <dax@happycoders.org>
## Started on  Wed Aug  9 21:04:42 2006 David Rousselie
## $Id$
##
## Copyright (C) 2006 David Rousselie
## This program 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 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY 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 this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##

"""FeederComponent with default Feeder and Sender
implementation"""

__revision__ = "$Id: feeder.py,v 1.3 2005/09/18 20:24:07 dax Exp $"

import logging

from jcl.jabber import Handler
from jcl.jabber.component import JCLComponent, AccountManager
from jcl.lang import Lang
from jcl.jabber.command import JCLCommandManager

from pyxmpp.message import Message

class FeederComponent(JCLComponent):
    """
    Implement a feeder sender behavior based on the
    regular interval behavior of JCLComponent
    feed data from given Feeder and send it to user
    through the given Sender.
    """

    def __init__(self,
                 jid,
                 secret,
                 server,
                 port,
                 config,
                 config_file,
                 lang=Lang(),
                 account_manager_class=AccountManager,
                 command_manager_class=JCLCommandManager):
        JCLComponent.__init__(self,
                              jid,
                              secret,
                              server,
                              port,
                              config,
                              config_file,
                              lang=lang,
                              account_manager_class=account_manager_class,
                              command_manager_class=command_manager_class)
        # Define default feeder and sender, can be override
        self.tick_handlers = [FeederHandler(Feeder(self), Sender(self))]
        self.__logger = logging.getLogger("jcl.jabber.FeederComponent")

    def handle_tick(self):
        """Implement main feed/send behavior"""
        for handler in self.tick_handlers:
            handler.handle(\
                None, self.lang.get_default_lang_class(),
                handler.filter(None,
                               self.lang.get_default_lang_class()))

class Feeder(object):
    """Abstract feeder class"""
    def __init__(self, component = None):
        self.component = component

    def feed(self, _account):
        """Feed data for given account"""
        raise NotImplementedError

class Sender(object):
    """Abstract sender class"""
    def __init__(self, component = None):
        self.component = component

    def send(self, to_account, subject, body):
        """Send data (subject and body) to given account"""
        raise NotImplementedError

class MessageSender(Sender):
    """Send data as Jabber Message"""

    def create_message(self, to_account, data):
        """Create message to send"""
        subject, body = data
        return Message(from_jid=to_account.jid,
                       to_jid=to_account.user.jid,
                       subject=subject,
                       body=body)

    def send(self, to_account, data):
        """Implement abstract method from Sender class and send
        data as Jabber message.
        """
        if self.component.stream is not None:
            self.component.stream.send(self.create_message(to_account,
                                                           data))

class HeadlineSender(MessageSender):
    """Send data as Jabber Headline"""

    def create_message(self, to_account, data):
        """Create headline to send"""
        subject, body = data
        return Message(from_jid=to_account.jid,
                       to_jid=to_account.user.jid,
                       subject=subject,
                       stanza_type="headline",
                       body=body)

class FeederHandler(Handler):
    """
    Filter (nothing by default) and call sender for each message from
    Feeder.
    """

    def __init__(self, feeder, sender):
        """DefaultFeederHandler constructor"""
        self.feeder = feeder
        self.sender = sender

    def handle(self, stanza, lang_class, data):
        """
        Apply actions to do on given accounts
        Do nothing by default.
        """
        for _account in data:
            if _account.enabled:
                for data in self.feeder.feed(_account):
                    if self.sender is not None:
                        self.sender.send(_account, data)
        return []
