/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/


#include "pyuno_impl.hxx"

#include <osl/thread.h>
#include <rtl/ustrbuf.hxx>

using rtl::OUStringToOString;
using rtl::OUString;
using com::sun::star::uno::Sequence;
using com::sun::star::uno::Reference;
using com::sun::star::uno::XInterface;
using com::sun::star::uno::Any;
using com::sun::star::uno::Type;
using com::sun::star::uno::TypeClass;
using com::sun::star::uno::RuntimeException;
using com::sun::star::uno::XComponentContext;
using com::sun::star::lang::XSingleServiceFactory;
using com::sun::star::script::XTypeConverter;
using com::sun::star::script::XInvocation2;

namespace pyuno
{
typedef struct
{
    Reference<XInvocation2> xInvocation;
    OUString methodName;
    ConversionMode mode;
} PyUNO_callable_Internals;

typedef struct
{
    PyObject_HEAD
    PyUNO_callable_Internals* members;
} PyUNO_callable;

void PyUNO_callable_del (PyObject* self)
{
    PyUNO_callable* me;
  
    me = (PyUNO_callable*) self;
    delete me->members;
    PyObject_Del (self);
  
    return;
}

PyObject* PyUNO_callable_call (PyObject* self, PyObject* args, PyObject*)
{
    PyUNO_callable* me;

    Sequence<short> aOutParamIndex;
    Sequence<Any> aOutParam;
    Sequence<Any> aParams;
    Sequence<Type> aParamTypes;
    Any any_params;
    Any out_params;
    Any ret_value;
    RuntimeCargo *cargo = 0;
    me = (PyUNO_callable*) self;
  
    PyRef ret;
    try
    {
        Runtime runtime;
        cargo = runtime.getImpl()->cargo;
        any_params = runtime.pyObject2Any (args, me->members->mode);
    
        if (any_params.getValueTypeClass () == com::sun::star::uno::TypeClass_SEQUENCE)
        {
            any_params >>= aParams;
        }
        else
        {
            aParams.realloc (1);
            aParams [0] <<= any_params;
        }

        {
            PyThreadDetach antiguard; //pyhton free zone
            
            // do some logging if desired ... 
            if( isLog( cargo, LogLevel::CALL ) )
            {
                logCall( cargo, "try     py->uno[0x", me->members->xInvocation.get(),
                         me->members->methodName, aParams );
            }

            // do the call
            ret_value = me->members->xInvocation->invoke (
                me->members->methodName, aParams, aOutParamIndex, aOutParam);

            // log the reply, if desired
            if( isLog( cargo, LogLevel::CALL ) )
            {
                logReply( cargo, "success py->uno[0x", me->members->xInvocation.get(),
                          me->members->methodName, ret_value, aOutParam);
            }
        }
        

        PyRef temp = runtime.any2PyObject (ret_value);
        if( aOutParam.getLength() )
        {
            PyRef return_list( PyTuple_New (1+aOutParam.getLength()), SAL_NO_ACQUIRE );
            PyTuple_SetItem (return_list.get(), 0, temp.getAcquired());

            // initialize with defaults in case of exceptions
            int i;
            for( i = 1 ; i < 1+aOutParam.getLength() ; i ++ )
            {
                Py_INCREF( Py_None );
                PyTuple_SetItem( return_list.get() , i , Py_None );
            }
            
            for( i = 0 ; i < aOutParam.getLength() ; i ++ )
            {
                PyRef ref = runtime.any2PyObject( aOutParam[i] );
                PyTuple_SetItem (return_list.get(), 1+i, ref.getAcquired());
            }
            ret = return_list;
        }
        else
        {
            ret = temp;
        }
    }
    catch( com::sun::star::reflection::InvocationTargetException & e )
    {
        
        if( isLog( cargo, LogLevel::CALL ) )
        {
            logException( cargo, "except  py->uno[0x", me->members->xInvocation.get() ,
                          me->members->methodName, e.TargetException.getValue(), e.TargetException.getValueTypeRef());
        }
        raisePyExceptionWithAny( e.TargetException );
    }
    catch( com::sun::star::script::CannotConvertException &e )
    {
        if( isLog( cargo, LogLevel::CALL ) )
        {
            logException( cargo, "error  py->uno[0x", me->members->xInvocation.get() ,
                          me->members->methodName, &e, getCppuType(&e).getTypeLibType());
        }
        raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
    }
    catch( com::sun::star::lang::IllegalArgumentException &e )
    {
        if( isLog( cargo, LogLevel::CALL ) )
        {
            logException( cargo, "error  py->uno[0x", me->members->xInvocation.get() ,
                          me->members->methodName, &e, getCppuType(&e).getTypeLibType());
        }
        raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
    }
    catch (::com::sun::star::uno::RuntimeException &e)
    {
        if( cargo && isLog( cargo, LogLevel::CALL ) )
        {
            logException( cargo, "error  py->uno[0x", me->members->xInvocation.get() ,
                          me->members->methodName, &e, getCppuType(&e).getTypeLibType());
        }
        raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
    }

    return ret.getAcquired();
}


static PyTypeObject PyUNO_callable_Type =
{
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    const_cast< char * >("PyUNO_callable"),
    sizeof (PyUNO_callable),
    0,
    (destructor) ::pyuno::PyUNO_callable_del,
    (printfunc) 0,
    (getattrfunc) 0,
    (setattrfunc) 0,
#if PY_MAJOR_VERSION >= 3
    0, 
#else
    (cmpfunc) 0,
#endif
    (reprfunc) 0,
    0,
    0,
    0,
    (hashfunc) 0,
    (ternaryfunc) ::pyuno::PyUNO_callable_call,
    (reprfunc) 0,
        (getattrofunc)0,
    (setattrofunc)0,
    NULL,
    0,
    NULL,
    (traverseproc)0,
    (inquiry)0,
    (richcmpfunc)0,
    0,
    (getiterfunc)0,
    (iternextfunc)0,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    (descrgetfunc)0,
    (descrsetfunc)0,
    0,
    (initproc)0,
    (allocfunc)0,
    (newfunc)0,
    (freefunc)0,
    (inquiry)0,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    (destructor)0
#if PY_VERSION_HEX >= 0x02060000
    , 0
#endif
};

PyRef PyUNO_callable_new (
    const Reference<XInvocation2> &my_inv,
    const OUString & methodName,
    enum ConversionMode mode )
{
    PyUNO_callable* self;
  
    self = PyObject_New (PyUNO_callable, &PyUNO_callable_Type);
    if (self == NULL)
        return NULL; //NULL == Error!

    self->members = new PyUNO_callable_Internals;
    self->members->xInvocation = my_inv;
    self->members->methodName = methodName;
    self->members->mode = mode;

    return PyRef( (PyObject*)self, SAL_NO_ACQUIRE );
}

}
