# Copyright (c) 2004 LOGILAB S.A. (Paris, FRANCE).
# http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# Copyright (c) 2004 DoCoMo Euro-Labs GmbH (Munich, Germany).
# http://www.docomolab-euro.com/ -- mailto:tarlano@docomolab-euro.com
#
# 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
"""basic actions to handle metalog

:version: $Revision:$  
:author: Logilab

:copyright:
  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: Metalog.py,v  $'

import os
old_cwd = os.getcwd()
from pymetalog.command import resolve#, is_metalog_syntax
os.chdir(old_cwd)

from narval.public import AL_NS, url_to_file
from narval.elements import create_command

DEFAULT_META_KB_FILE_URL = 'file:$NARVAL_HOME/data/kb.ml'

def meta_file(obj=None):
    """return the path to the knowledge file and it's encoding

    :param obj: object adaptable to IURL

    :rtype: tuple(str, str)
    """
    return url_to_file(obj, DEFAULT_META_KB_FILE_URL)


MOD_XML = '''<?xml version="1.0" encoding="ISO-8859-1"?>
<module name="Metalog" xmlns:al='%s'>''' % AL_NS

def handle_metalog(inputs):
    """
    handle a (possibly) metalog insertion or query
    """
    msg = inputs['msg']
    #if is_metalog_syntax(msg.get_body()):
    if msg.get_body().strip()[-1] == '?':
        return {'command': create_command('query-metalog', [msg.get_body()])}
    elif msg.get_body().strip()[-1] == '.':
        return {'command': create_command('insert-metalog', [msg.get_body()])}
    return {}

MOD_XML = MOD_XML + """
<al:action name='handle-metalog' func='handle_metalog'>
  <al:description lang='en'>Handle 'search' command : grep a log file</al:description>

  <al:input id='msg' use='yes'>
    <al:match>IIMessage(elmt).type == 'incoming'</al:match>
  </al:input>
  
  <al:output id='command' optionnal='yes'>
    <al:match>ICommand(elmt)</al:match>
  </al:output>
</al:action>"""

def query_metalog(inputs):
    """
    Attempts to answer the question by delegating to metalog1
    """
    msg = inputs['msg']
    path, encoding = meta_file(inputs['metalog_kb'])
    stream = open(path, 'r')
    kb_string = stream.read()
    stream.close()
    try:
        answer = resolve(kb_string, msg.get_body()+'\n\n\n')
    except:
        import traceback
        log(LOG_ERR, 'Failed metalog resolve')
        traceback.print_exc()
        return {'msg' : msg.build_reply('failed to query metalog')}
    return {'msg' : msg.build_reply(answer)}

MOD_XML = MOD_XML + """
<al:action name='query-metalog' func='query_metalog'>
  <al:description lang='en'>Handle 'search' command : grep a log file</al:description>

  <al:input id='msg' use='yes'>
    <al:match>IIMessage(elmt).type == 'incoming'</al:match>
  </al:input>
  <al:input id='metalog_kb' optional='yes'>
    <al:match>elmt.getattr((TYPE_NS, 'name')) == 'uri:memory:metalog-kb'</al:match>
    <al:match>IURL(elmt)</al:match>
  </al:input>
  
  <al:output id='msg' use='yes'>
    <al:match>IIMessage(elmt)</al:match>
  </al:output>
</al:action>"""

def insert_metalog(inputs):
    """
    Insert a statement into the metalog knowledge base
    """
    msg = inputs['msg']
    path, encoding = meta_file(inputs['metalog_kb'])
    stream = open(path, 'a+')
    stream.write(msg.get_body()+'\n')
    stream.close()
    return {'msg':msg.build_reply('inserted into metalog kb')}

MOD_XML = MOD_XML + """
<al:action name='insert-metalog' func='insert_metalog'>
  <al:description lang='en'>Handle 'search' command : grep a log file</al:description>

  <al:input id='msg' use='yes'>
    <al:match>IIMessage(elmt).type == 'incoming'</al:match>
  </al:input>
  <al:input id='metalog_kb' optional='yes'>
    <al:match>elmt.getattr((TYPE_NS, 'name')) == 'uri:memory:metalog-kb'</al:match>
    <al:match>IURL(elmt)</al:match>
  </al:input>

  <al:output id='msg' use='yes'>
    <al:match>IIMessage(elmt)</al:match>
  </al:output>
</al:action>"""

MOD_XML +=  "</module>"
