# Copyright (c) 2004 DoCoMo Euro-Labs GmbH (Munich, Germany).
# Copyright (c) 2001-2004 LOGILAB S.A. (Paris, FRANCE).
#
# http://www.docomolab-euro.com/ -- mailto:tarlano@docomolab-euro.com
# http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
"""implementations of some listener interfaces


:version: $Revision:$  
:author: Logilab

:copyright:
  2001-2004 LOGILAB S.A. (Paris, FRANCE)
  
  2004 DoCoMo Euro-Labs GmbH (Munich, Germany)
  
:contact:
  http://www.logilab.fr/ -- mailto:contact@logilab.fr
  
  http://www.docomolab-euro.com/ -- mailto:tarlano@docomolab-euro.com
"""

__revision__ = "$Id: PlanListener.py,v 1.10 2001/11/06 13:30:39 alf Exp $"
__docformat__ = "restructuredtext en"


from narval.engine_interfaces import IPlanListener, IMemoryListener


class MemoryListenerImpl(object):
    """IMemoryListener implementation (pass on everything)"""
    __implements__ = (IMemoryListener,)
    
    def add_element(self, eid):
        """a new element has been added to the memory

        :type eid: int
        :param eid: the eid of the newly added element
        """
    
    def remove_element(self, eid):
        """an element has been removed from the memory

        :type eid: int
        :param eid: the eid of the removed element
        """

    def replace_element(self, eid):
        """an element has been replaced from the memory

        :type eid: int
        :param eid: the eid of the replaced element
        """

class PlanListenerImpl(object):
    """IPlanListener implementation (pass on everything)"""
    __implements__ = (IPlanListener,)
    
    def fire_transition(self, plan_eid, transition_eid):
        """a transition has been fired

        :type plan_eid: int
        :param plan_eid: the eid of the plan where the transition has been fired

        :type transition_eid: int
        :param transition_eid: the eid of the transition which has been fired
        """

    def transition_status_changed(self, plan_eid, transition_eid, status):
        """a transition's status changed

        :type plan_eid: int
        :param plan_eid: the eid of the plan where the transition has changed

        :type transition_eid: int
        :param transition_eid: the eid of the transition which has changed

        :type status: str
        :param status: the new transition's status
        """

    def step_status_changed(self, plan_eid, step_eid, status):
        """a step's status changed

        :type plan_eid: int
        :param plan_eid: the eid of the plan where the step has changed

        :type step_eid: int
        :param step_eid: the eid of the step which has changed

        :type status: str
        :param status: the new step's status
        """

    def plan_status_changed(self, plan_eid, status):
        """a plan's status changed

        :type plan_eid: int
        :param plan_eid: the eid of the plan which has changed

        :type status: str
        :param status: the new step's status
        """

    def instanciate_recipe(self, plan_eid, recipe_name):
        """a recipe has been instantiated

        :type plan_eid: int
        :param plan_eid: the eid of the plan which has been instantiated
        
        :type recipe_name: str
        :param recipe_name:
          the name of the recipe instantiated (<cookbook>.<recipe>)
        """

    def plan_add_element(self, plan_eid, eid):
        """an element has been added from the plan

        :type plan_eid: int
        :param plan_eid: the eid of the plan where the element has been added
        
        :type eid: int
        :param eid: the eid of the element which has been added
        """
        
    def plan_remove_element(self, plan_eid, eid):
        """an element has been removed from the plan

        :type plan_eid: int
        :param plan_eid: the eid of the plan where the element has been removed
        
        :type eid: int
        :param eid: the eid of the element which has been removed
        """

class MemoryListenerLogImpl(object):
    """IMemoryListener implementation (log everything)

    :type severity: int
    :ivar severity: severity used to log message (default to LOG_INFO)
    """
    __implements__ = (IMemoryListener,)

    def __init__(self, severity=None):
        super(MemoryListenerLogImpl, self).__init__()
        self.severity = severity or LOG_INFO
        
    def add_element(self, eid):
        """a new element has been added to the memory

        :type eid: int
        :param eid: the eid of the newly added element
        """
        log(self.severity, "added element %s to memory", eid)

    def remove_element(self, eid):
        """an element has been removed from the memory

        :type eid: int
        :param eid: the eid of the removed element
        """
        log(self.severity, "removed element %s from memory", eid)

    def replace_element(self, eid):
        """an element has been replaced from the memory

        :type eid: int
        :param eid: the eid of the replaced element
        """
        log(self.severity, 'replaced element %s in memory', eid)


class PlanListenerLogImpl(object):
    """IPlanListener implementation (log everything)

    :type plans_dict: dict
    :ivar plans_dict: dictionary mapping plan eid to recipe name

    :type severity: int
    :ivar severity: severity used to log message (default to LOG_INFO)
    """
    __implements__ = (IPlanListener,)
    
    def __init__(self, severity=None):
        super(PlanListenerLogImpl, self).__init__()
        self.plans_dict = {}
        self.severity = severity or LOG_INFO
        
    def fire_transition(self, plan_eid, transition_eid):
        """a transition has been fired

        :type plan_eid: int
        :param plan_eid: the eid of the plan where the transition has been fired

        :type transition_eid: int
        :param transition_eid: the eid of the transition which has been fired
        """
        log(self.severity, "plan %s\t(%s) firing transition %s",
            (plan_eid, self.plans_dict[plan_eid][:15].ljust(15), transition_eid))

    def transition_status_changed(self, plan_eid, transition_eid, status):
        """a transition's status changed

        :type plan_eid: int
        :param plan_eid: the eid of the plan where the transition has changed

        :type transition_eid: int
        :param transition_eid: the eid of the transition which has changed

        :type status: str
        :param status: the new transition's status
        """
        log(self.severity, "plan %s (%s) trans. %s --> %s",
            (plan_eid, self.plans_dict[plan_eid][:15].ljust(15), transition_eid, status))

    def step_status_changed(self, plan_eid, step_eid, status):
        """a step's status changed

        :type plan_eid: int
        :param plan_eid: the eid of the plan where the step has changed

        :type step_eid: int
        :param step_eid: the eid of the step which has changed

        :type status: str
        :param status: the new step's status
        """
        log(self.severity, "plan %s (%s) step   %s --> %s",
            (plan_eid,self. plans_dict[plan_eid][:15].ljust(15), step_eid, status))

    def plan_status_changed(self, plan_eid, status):
        """a plan's status changed

        :type plan_eid: int
        :param plan_eid: the eid of the plan which has changed

        :type status: str
        :param status: the new step's status
        """
        log(self.severity, "plan %s (%s) status --> %s",
            (plan_eid, self.plans_dict[plan_eid][:15].ljust(15),status))

    def instanciate_recipe(self, plan_eid, recipe_name):
        """a recipe has been instantiated

        :type plan_eid: int
        :param plan_eid: the eid of the plan which has been instantiated
        
        :type recipe_name: str
        :param recipe_name:
          the name of the recipe instantiated (<cookbook>.<recipe>)
        """
        self.plans_dict[plan_eid] = recipe_name
        log(self.severity, "plan %s (%s) instantiated", (plan_eid,
                                                 recipe_name[:15].ljust(15)))

    def plan_add_element(self, plan_eid, eid):
        """an element has been added from the plan

        :type plan_eid: int
        :param plan_eid: the eid of the plan where the element has been added
        
        :type eid: int
        :param eid: the eid of the element which has been added
        """
        log(self.severity, "added element %s to plan %s", (eid, plan_eid))
        
    def plan_remove_element(self, plan_eid, eid):
        """an element has been removed from the plan

        :type plan_eid: int
        :param plan_eid: the eid of the plan where the element has been removed
        
        :type eid: int
        :param eid: the eid of the element which has been removed
        """
        log(self.severity, "removed element %s from plan %s", (eid, plan_eid))

