/**************************************************************
 * 
 * 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 "sal/config.h"

#include <list>
#include <vector>

#include "boost/noncopyable.hpp"
#include "com/sun/star/bridge/XInstanceProvider.hpp"
#include "cppuhelper/exc_hlp.hxx"
#include "rtl/byteseq.hxx"
#include "rtl/ref.hxx"
#include "rtl/ustring.hxx"
#include "sal/types.h"
#include "typelib/typedescription.hxx"
#include "uno/dispatcher.hxx"

#include "binaryany.hxx"
#include "bridge.hxx"
#include "currentcontext.hxx"
#include "incomingrequest.hxx"
#include "specialfunctionids.hxx"

namespace binaryurp {

namespace {

namespace css = com::sun::star;

}

IncomingRequest::IncomingRequest(
    rtl::Reference< Bridge > const & bridge, rtl::ByteSequence const & tid,
    rtl::OUString const & oid, css::uno::UnoInterfaceReference const & object,
    css::uno::TypeDescription const & type, sal_uInt16 functionId,
    bool synchronous, css::uno::TypeDescription const & member, bool setter,
    std::vector< BinaryAny > const & inArguments, bool currentContextMode,
    css::uno::UnoInterfaceReference const & currentContext):
    bridge_(bridge), tid_(tid), oid_(oid), object_(object), type_(type),
    functionId_(functionId), synchronous_(synchronous), member_(member),
    setter_(setter), inArguments_(inArguments),
    currentContextMode_(currentContextMode), currentContext_(currentContext)
{
    OSL_ASSERT(bridge.is() && member.is() && member.get()->bComplete);
}

IncomingRequest::~IncomingRequest() {}

void IncomingRequest::execute() const {
    BinaryAny ret;
    std::vector< BinaryAny > outArgs;
    bool isExc;
    try {
        bool resetCc = false;
        css::uno::UnoInterfaceReference oldCc;
        if (currentContextMode_) {
            oldCc = current_context::get();
            current_context::set(currentContext_);
            resetCc = true;
        }
        try {
            try {
                isExc = !execute_throw(&ret, &outArgs);
            } catch (std::exception & e) {
                throw css::uno::RuntimeException(
                    (rtl::OUString(
                        RTL_CONSTASCII_USTRINGPARAM("caught C++ exception: ")) +
                     rtl::OStringToOUString(
                         rtl::OString(e.what()), RTL_TEXTENCODING_ASCII_US)),
                    css::uno::Reference< css::uno::XInterface >());
                    // best-effort string conversion
            }
        } catch (css::uno::RuntimeException &) {
            css::uno::Any exc(cppu::getCaughtException());
            ret = bridge_->mapCppToBinaryAny(exc);
            isExc = true;
        }
        if (resetCc) {
            current_context::set(oldCc);
        }
    } catch (css::uno::RuntimeException &) {
        css::uno::Any exc(cppu::getCaughtException());
        ret = bridge_->mapCppToBinaryAny(exc);
        isExc = true;
    }
    if (synchronous_) {
        bridge_->decrementActiveCalls();
        try {
            bridge_->getWriter()->queueReply(
                tid_, member_, setter_, isExc, ret, outArgs, false);
            return;
        } catch (css::uno::RuntimeException & e) {
            OSL_TRACE(
                OSL_LOG_PREFIX "caught UNO runtime exception '%s'",
                (rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).
                 getStr()));
        } catch (std::exception & e) {
            OSL_TRACE(OSL_LOG_PREFIX "caught C++ exception '%s'", e.what());
        }
        bridge_->terminate();
    } else {
        if (isExc) {
            OSL_TRACE(OSL_LOG_PREFIX "oneway method raised exception");
        }
        bridge_->decrementCalls();
    }
}

bool IncomingRequest::execute_throw(
    BinaryAny * returnValue, std::vector< BinaryAny > * outArguments) const
{
    OSL_ASSERT(
        returnValue != 0 &&
        returnValue->getType().equals(
            css::uno::TypeDescription(
                cppu::UnoType< cppu::UnoVoidType >::get())) &&
        outArguments != 0 && outArguments->empty());
    bool isExc = false;
    switch (functionId_) {
    case SPECIAL_FUNCTION_ID_RESERVED:
        OSL_ASSERT(false); // this cannot happen
        break;
    case SPECIAL_FUNCTION_ID_RELEASE:
        bridge_->releaseStub(oid_, type_);
        break;
    case SPECIAL_FUNCTION_ID_QUERY_INTERFACE:
        if (!object_.is()) {
            css::uno::Reference< css::uno::XInterface > ifc;
            css::uno::Reference< css::bridge::XInstanceProvider > prov(
                bridge_->getProvider());
            if (prov.is()) {
                try {
                    ifc = prov->getInstance(oid_);
                } catch (css::container::NoSuchElementException & e) {
                    OSL_TRACE(
                        (OSL_LOG_PREFIX "initial element '%s':"
                         " NoSuchElementException '%s'"),
                        (rtl::OUStringToOString(oid_, RTL_TEXTENCODING_UTF8).
                         getStr()),
                        (rtl::OUStringToOString(
                            e.Message, RTL_TEXTENCODING_UTF8).
                         getStr()));
                }
            }
            if (ifc.is()) {
                css::uno::UnoInterfaceReference unoIfc(
                    static_cast< uno_Interface * >(
                        bridge_->getCppToBinaryMapping().mapInterface(
                            ifc.get(),
                            (css::uno::TypeDescription(
                                cppu::UnoType<
                                    css::uno::Reference<
                                        css::uno::XInterface > >::get()).
                             get()))),
                    SAL_NO_ACQUIRE);
                *returnValue = BinaryAny(
                    css::uno::TypeDescription(
                        cppu::UnoType<
                            css::uno::Reference<
                                css::uno::XInterface > >::get()),
                    &unoIfc.m_pUnoI);
            }
            break;
        }
        // fall through
    default:
        {
            OSL_ASSERT(object_.is());
            css::uno::TypeDescription retType;
            std::list< std::vector< char > > outBufs;
            std::vector< void * > args;
            switch (member_.get()->eTypeClass) {
            case typelib_TypeClass_INTERFACE_ATTRIBUTE:
                {
                    css::uno::TypeDescription t(
                        reinterpret_cast<
                            typelib_InterfaceAttributeTypeDescription * >(
                                member_.get())->
                        pAttributeTypeRef);
                    if (setter_) {
                        OSL_ASSERT(inArguments_.size() == 1);
                        args.push_back(inArguments_[0].getValue(t));
                    } else {
                        OSL_ASSERT(inArguments_.empty());
                        retType = t;
                    }
                    break;
                }
            case typelib_TypeClass_INTERFACE_METHOD:
                {
                    typelib_InterfaceMethodTypeDescription * mtd =
                        reinterpret_cast<
                            typelib_InterfaceMethodTypeDescription * >(
                                member_.get());
                    retType = css::uno::TypeDescription(mtd->pReturnTypeRef);
                    std::vector< BinaryAny >::const_iterator i(
                        inArguments_.begin());
                    for (sal_Int32 j = 0; j != mtd->nParams; ++j) {
                        void * p;
                        if (mtd->pParams[j].bIn) {
                            p = i++->getValue(
                                css::uno::TypeDescription(
                                    mtd->pParams[j].pTypeRef));
                        } else {
                            outBufs.push_back(
                                std::vector< char >(
                                    css::uno::TypeDescription(
                                        mtd->pParams[j].pTypeRef).
                                    get()->nSize));
                            p = &outBufs.back()[0];
                        }
                        args.push_back(p);
                        if (mtd->pParams[j].bOut) {
                            outArguments->push_back(BinaryAny());
                        }
                    }
                    OSL_ASSERT(i == inArguments_.end());
                    break;
                }
            default:
                OSL_ASSERT(false); // this cannot happen
                break;
            }
            std::vector< char > retBuf(retType.is() ? retType.get()->nSize : 0);
            uno_Any exc;
            uno_Any * pexc = &exc;
            (*object_.get()->pDispatcher)(
                object_.get(), member_.get(), retBuf.empty() ? 0 : &retBuf[0],
                args.empty() ? 0 : &args[0], &pexc);
            isExc = pexc != 0;
            if (isExc) {
                *returnValue = BinaryAny(
                    css::uno::TypeDescription(
                        cppu::UnoType< css::uno::Any >::get()),
                    &exc);
                uno_any_destruct(&exc, 0);
            } else {
                if (!retBuf.empty()) {
                    *returnValue = BinaryAny(retType, &retBuf[0]);
                    uno_destructData(&retBuf[0], retType.get(), 0);
                }
                if (!outArguments->empty()) {
                    OSL_ASSERT(
                        member_.get()->eTypeClass ==
                        typelib_TypeClass_INTERFACE_METHOD);
                    typelib_InterfaceMethodTypeDescription * mtd =
                        reinterpret_cast<
                            typelib_InterfaceMethodTypeDescription * >(
                                member_.get());
                    std::vector< BinaryAny >::iterator i(outArguments->begin());
                    std::list< std::vector< char > >::iterator j(
                        outBufs.begin());
                    for (sal_Int32 k = 0; k != mtd->nParams; ++k) {
                        if (mtd->pParams[k].bOut) {
                            *i++ = BinaryAny(
                                css::uno::TypeDescription(
                                    mtd->pParams[k].pTypeRef),
                                args[k]);
                        }
                        if (!mtd->pParams[k].bIn) {
                            uno_type_destructData(
                                &(*j++)[0], mtd->pParams[k].pTypeRef, 0);
                        }
                    }
                    OSL_ASSERT(i == outArguments->end());
                    OSL_ASSERT(j == outBufs.end());
                }
            }
            break;
        }
    }
    return !isExc;
}

}
