# 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
'''This module is intended to be used with the test suite in
Narval/tools/tests/cases.

Do not expect anything useful from the actions defined here.
'''

__revision__ = "$Id: Selftest.py,v 1.8 2003/01/30 09:26:33 syt Exp $"

from narval.elements import create_error
from narval.elements.test import Element

MOD_XML='''<?xml version="1.0" encoding="ISO-8859-1"?>
<module name="Selftest" xmlns:al="http://www.logilab.org/namespaces/Narval/1.2">'''

def NOP_f(inputs) :
    """No OPeration"""
    return {}

MOD_XML = MOD_XML + "<al:action name='NOP' func='NOP_f'/>"


def produce_element_f(inputs):
    """output an element"""
    return {'output': Element()}

MOD_XML = MOD_XML + """<al:action name='produce_element' func='produce_element_f'>
  <al:output id='output'><al:match>isinstance(elmt, Element)</al:match></al:output>
</al:action>
"""


def produce_error_f(inputs):
    """output an error element"""
    return {'error': [create_error('yo')]}

MOD_XML = MOD_XML + """<al:action name='produce_error' func='produce_error_f'>
  <al:output id='output'><al:match>elmt.whatever</al:match></al:output>
</al:action>
"""

MOD_XML = MOD_XML + """<al:action name='produce_wrong_element' func='produce_element_f'>
  <al:output id='output'><al:match>isinstance(elmt, str)</al:match></al:output>
</al:action>
"""

MOD_XML = MOD_XML + """<al:action name='produce_optional_element' func='NOP_f'>
  <al:output id='output' optional='yes'><al:match>isinstance(elmt, Element)</al:match></al:output>
</al:action>
"""


def produce_multiple_elements_f(inputs):
    """output multiple elements"""
    return {'output': [Element(), Element(), Element()]}

MOD_XML = MOD_XML + """<al:action name='produce_multiple_element' func='produce_multiple_elements_f'>
  <al:output id='output' list='yes'><al:match>isinstance(elmt, Element)</al:match></al:output>
</al:action>
"""

MOD_XML = MOD_XML + """<al:action name='produce_wrong_element_count' func='produce_multiple_elements_f'>
  <al:output id='output'><al:match>isinstance(elmt, Element)</al:match></al:output>
</al:action>
"""

MOD_XML = MOD_XML + """<al:action name='produce_empty_list' func='NOP_f'>
  <al:output id='output' list='yes'><al:match>isinstance(elmt, Element)</al:match></al:output>
</al:action>
"""

MOD_XML = MOD_XML + """<al:action name='produce_optional_list' func='NOP_f'>
  <al:output id='output' list='yes' optional='yes'><al:match>isinstance(elmt, Element)</al:match></al:output>
</al:action>
"""


def naughty_action_f(inputs):
    """Bad behaviour in action"""
    return None

MOD_XML = MOD_XML + """<al:action name='naughty_action' func='naughty_action_f'>
  <al:output id='output' list='yes'><al:match>isinstance(elmt, Element)</al:match></al:output>
</al:action>
"""

# Bad behaviour in action : no stub exist in module############################
MOD_XML = MOD_XML + """<al:action name='naughty_action_2' func='non_existent_f'>
  <al:output id='output' list='yes'><al:match>isinstance(elmt, Element)</al:match></al:output>
</al:action>
"""

def produce_wrong_multiple_elements_f(inputs):
    """Bad behaviour in action : outputs multiple elements with one wrong type"""
    class DummyElement:
        def as_xml(self, encoding='UTF-8'):
            return '<dummy/>'
    return {'output': [Element(),
                       DummyElement(), # list DummyElement instead of Element instance
                       Element()]}

MOD_XML = MOD_XML + """<al:action name='produce_wrong_multiple_element' func='produce_wrong_multiple_elements_f'>
  <al:output id='output' list='yes'><al:match>isinstance(elmt, Element)</al:match></al:output>
</al:action>
"""

def raise_exception_f(inputs):
    """Bad behaviour in action : exception raised"""
    raise 'Bouahahahahahaha!'

MOD_XML = MOD_XML + "<al:action name='raise_exception' func='raise_exception_f'/>"


#   ###########################

def identity_f(inputs):
    """identity function: copies its input to its ouput"""
    out = {}
    # if the input element has a flag attribute, things will be fine
    # otherwise, we'll get an error
    for id, elmt in inputs.items():
        try:
            elmt = elmt.clone()
            out[id] = elmt
            elmt.identity = 1
        except:
            # list argument ?
            out[id] = res = []
            for elmt_ in elmt:
                elmt_ = elmt_.clone()
                elmt_.identity = 1
                res.append(elmt_)
    return out

# outdates optional
MOD_XML = MOD_XML + """<al:action name='test_outdates_opts' func='identity_f'>
    <al:description lang="en">outdates all elements of the optional list</al:description>
    <al:input optional='yes' list='yes' id='list1'><al:match>isinstance(elmt, Element) and elmt.el_id</al:match></al:input>
    <al:input optional='yes' list='yes' id='list2'><al:match>isinstance(elmt, str)</al:match></al:input>
    <al:input id='test1'><al:match>elmt.attribute == "test"</al:match></al:input>
    <al:output id='list1' list="yes" outdates='list1'><al:match>isinstance(elmt, Element) and elmt.el_id</al:match></al:output>
    <al:output id='list2' list="yes" optional='yes'><al:match>isinstance(elmt, str)</al:match></al:output>
    <al:output id='test1' list="yes"><al:match>elmt.attribute == "test"</al:match></al:output>
</al:action>
"""

# match should be given in the recipe
MOD_XML = MOD_XML + """<al:action name='test_io_id' func='identity_f'>
  <al:input id='element'/>
  <al:output id='element'/>
</al:action>
"""
# action expects more than what is specified in the prototype
# so that we can test the context from which the element is selected
MOD_XML = MOD_XML + """<al:action name='test_input' func='identity_f'>
  <al:input id='element'><al:match>isinstance(elmt, Element)</al:match></al:input>
  <al:output id='element'><al:match>isinstance(elmt, Element) and elmt.identity</al:match></al:output>
</al:action>
"""

MOD_XML = MOD_XML + """<al:action name='test_input_list' func='identity_f'>
  <al:input id='element' list='yes'><al:match>isinstance(elmt, Element)</al:match></al:input>
  <al:output id='element' list='yes'><al:match>elmt.identity</al:match></al:output>
</al:action>
"""

# copies the input element to the output
MOD_XML = MOD_XML + """<al:action name='test_input_nice' func='identity_f'>
  <al:input id='element'><al:match>isinstance(elmt, Element)</al:match></al:input>
  <al:output id='element'><al:match>isinstance(elmt, Element)</al:match></al:output>
</al:action>
"""

# eats a list of arguments
MOD_XML = MOD_XML + """<al:action name='test_input_nice' func='NOP_f'>
  <al:input id='element' list='yes'><al:match>isinstance(elmt, Element)</al:match></al:input>
</al:action>
"""

MOD_XML = MOD_XML +'</module>'
