/**************************************************************
 * 
 * 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 <exception>
#include <memory>
#include <vector>

#include "com/sun/star/connection/XConnection.hpp"
#include "com/sun/star/io/IOException.hpp"
#include "com/sun/star/uno/Any.hxx"
#include "com/sun/star/uno/Exception.hpp"
#include "com/sun/star/uno/Reference.hxx"
#include "com/sun/star/uno/RuntimeException.hpp"
#include "com/sun/star/uno/Sequence.hxx"
#include "com/sun/star/uno/Type.hxx"
#include "com/sun/star/uno/XCurrentContext.hpp"
#include "com/sun/star/uno/XInterface.hpp"
#include "cppu/unotype.hxx"
#include "osl/diagnose.h"
#include "rtl/byteseq.h"
#include "rtl/string.h"
#include "rtl/textenc.h"
#include "rtl/ustring.h"
#include "rtl/ustring.hxx"
#include "sal/types.h"
#include "typelib/typeclass.h"
#include "typelib/typedescription.h"
#include "typelib/typedescription.hxx"
#include "uno/lbnames.h"

#include "binaryany.hxx"
#include "bridge.hxx"
#include "incomingreply.hxx"
#include "incomingrequest.hxx"
#include "outgoingrequest.hxx"
#include "reader.hxx"
#include "specialfunctionids.hxx"
#include "unmarshal.hxx"

namespace binaryurp {

namespace {

namespace css = com::sun::star;

css::uno::Sequence< sal_Int8 > read(
    css::uno::Reference< css::connection::XConnection > const & connection,
    sal_uInt32 size, bool eofOk)
{
    OSL_ASSERT(connection.is());
    if (size > SAL_MAX_INT32) {
        throw css::uno::RuntimeException(
            rtl::OUString(
                RTL_CONSTASCII_USTRINGPARAM(
                    "binaryurp::Reader: block size too large")),
            css::uno::Reference< css::uno::XInterface >());
    }
    css::uno::Sequence< sal_Int8 > buf;
    sal_Int32 n = connection->read(buf, static_cast< sal_Int32 >(size));
    if (n == 0 && eofOk) {
        return css::uno::Sequence< sal_Int8 >();
    }
    if (n != static_cast< sal_Int32 >(size)) {
        throw css::io::IOException(
            rtl::OUString(
                RTL_CONSTASCII_USTRINGPARAM(
                    "binaryurp::Reader: premature end of input")),
            css::uno::Reference< css::uno::XInterface >());
    }
    OSL_ASSERT(buf.getLength() == static_cast< sal_Int32 >(size));
    return buf;
}

extern "C" void SAL_CALL request(void * pThreadSpecificData) {
    OSL_ASSERT(pThreadSpecificData != 0);
    std::auto_ptr< IncomingRequest >(
        static_cast< IncomingRequest * >(pThreadSpecificData))->
        execute();
}

}

Reader::Reader(rtl::Reference< Bridge > const & bridge): bridge_(bridge) {
    OSL_ASSERT(bridge.is());
    acquire();
}

Reader::~Reader() {}

void Reader::run() {
    setName("binaryurpReader");
    try {
        bridge_->sendRequestChangeRequest();
        css::uno::Reference< css::connection::XConnection > con(
            bridge_->getConnection());
        for (;;) {
            css::uno::Sequence< sal_Int8 > s(read(con, 8, true));
            if (s.getLength() == 0) {
                break;
            }
            Unmarshal header(bridge_, state_, s);
            sal_uInt32 size = header.read32();
            sal_uInt32 count = header.read32();
            header.done();
            if (count == 0) {
                throw css::io::IOException(
                    rtl::OUString(
                        RTL_CONSTASCII_USTRINGPARAM(
                            "binaryurp::Reader: block with zero message count"
                            " received")),
                    css::uno::Reference< css::uno::XInterface >());
            }
            Unmarshal block(bridge_, state_, read(con, size, false));
            for (sal_uInt32 i = 0; i != count; ++i) {
                readMessage(block);
            }
            block.done();
        }
    } catch (css::uno::Exception & e) {
        OSL_TRACE(
            OSL_LOG_PREFIX "caught UNO 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();
}

void Reader::onTerminated() {
    release();
}

void Reader::readMessage(Unmarshal & unmarshal) {
    sal_uInt8 flags1 = unmarshal.read8();
    bool newType;
    bool newOid;
    bool newTid;
    bool forceSynchronous;
    sal_uInt16 functionId;
    if ((flags1 & 0x80) != 0) { // bit 7: LONGHEADER
        if ((flags1 & 0x40) == 0) { // bit 6: REQUEST
            readReplyMessage(unmarshal, flags1);
            return;
        }
        newType = (flags1 & 0x20) != 0; // bit 5: NEWTYPE
        newOid = (flags1 & 0x10) != 0; // bit 4: NEWOID
        newTid = (flags1 & 0x08) != 0; // bit 3: NEWTID
        if ((flags1 & 0x01) != 0) { // bit 0: MOREFLAGSS
            sal_uInt8 flags2 = unmarshal.read8();
            forceSynchronous = (flags2 & 0x80) != 0; // bit 7: MUSTREPLY
            if (((flags2 & 0x40) != 0) != forceSynchronous) {
                    // bit 6: SYNCHRONOUS
                throw css::uno::RuntimeException(
                    rtl::OUString(
                        RTL_CONSTASCII_USTRINGPARAM(
                            "URP: request message with MUSTREPLY != SYNCHRONOUS"
                            " received")),
                    css::uno::Reference< css::uno::XInterface >());
            }
        } else {
            forceSynchronous = false;
        }
        functionId = ((flags1 & 0x04) != 0) // bit 2: FUNCTIONID16
            ? unmarshal.read16() : unmarshal.read8();
    } else {
        newType = false;
        newOid = false;
        newTid = false;
        forceSynchronous = false;
        functionId = ((flags1 & 0x40) != 0) // bit 6: FUNCTIONID14
            ? ((flags1 & 0x3F) << 8) | unmarshal.read8() : flags1 & 0x3F;
    }
    css::uno::TypeDescription type;
    if (newType) {
        type = unmarshal.readType();
        lastType_ = type;
    } else {
        if (!lastType_.is()) {
            throw css::uno::RuntimeException(
                rtl::OUString(
                    RTL_CONSTASCII_USTRINGPARAM(
                        "URP: request message with NEWTYPE received when last"
                        " interface type has not yet been set")),
                css::uno::Reference< css::uno::XInterface >());
        }
        type = lastType_;
    }
    rtl::OUString oid;
    if (newOid) {
        oid = unmarshal.readOid();
        if ( oid.isEmpty() ) {
            throw css::io::IOException(
                rtl::OUString(
                    RTL_CONSTASCII_USTRINGPARAM(
                        "binaryurp::Unmarshal: emtpy OID")),
                css::uno::Reference< css::uno::XInterface >());
        }
        lastOid_ = oid;
    } else {
        if ( lastOid_.isEmpty() ) {
            throw css::uno::RuntimeException(
                rtl::OUString(
                    RTL_CONSTASCII_USTRINGPARAM(
                        "URP: request message with NEWOID received when last"
                        " OID has not yet been set")),
                css::uno::Reference< css::uno::XInterface >());
        }
        oid = lastOid_;
    }
    rtl::ByteSequence tid(getTid(unmarshal, newTid));
    lastTid_ = tid;
    type.makeComplete();
    if (type.get()->eTypeClass != typelib_TypeClass_INTERFACE) {
        throw css::uno::RuntimeException(
            rtl::OUString(
                RTL_CONSTASCII_USTRINGPARAM(
                    "URP: request message with non-interface interface type"
                    " received")),
            css::uno::Reference< css::uno::XInterface >());
    }
    typelib_InterfaceTypeDescription * itd =
        reinterpret_cast< typelib_InterfaceTypeDescription * >(type.get());
    if (functionId >= itd->nMapFunctionIndexToMemberIndex) {
        throw css::uno::RuntimeException(
            rtl::OUString(
                RTL_CONSTASCII_USTRINGPARAM(
                    "URP: request message with unknown function ID received")),
            css::uno::Reference< css::uno::XInterface >());
    }
    sal_Int32 memberId = itd->pMapFunctionIndexToMemberIndex[functionId];
    css::uno::TypeDescription memberTd(itd->ppAllMembers[memberId]);
    memberTd.makeComplete();
    OSL_ASSERT(memberTd.is());
    bool protProps = bridge_->isProtocolPropertiesRequest(oid, type);
    bool ccMode = !protProps && functionId != SPECIAL_FUNCTION_ID_RELEASE &&
        bridge_->isCurrentContextMode();
    css::uno::UnoInterfaceReference cc;
    if (ccMode) {
        css::uno::TypeDescription t(
            cppu::UnoType< css::uno::Reference< css::uno::XCurrentContext > >::
            get());
        cc.set(
            *static_cast< uno_Interface ** >(
                unmarshal.readValue(t).getValue(t)));
    }
    bool synchronous;
    if (memberTd.get()->eTypeClass == typelib_TypeClass_INTERFACE_METHOD &&
        (reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
            memberTd.get())->
         bOneWay))
    {
        synchronous = forceSynchronous;
    } else {
        if (forceSynchronous) {
            throw css::uno::RuntimeException(
                rtl::OUString(
                    RTL_CONSTASCII_USTRINGPARAM(
                        "URP: synchronous request message with non-oneway"
                        " function ID received")),
                css::uno::Reference< css::uno::XInterface >());
        }
        synchronous = true;
    }
    bool setter = false;
    std::vector< BinaryAny > inArgs;
    switch (memberTd.get()->eTypeClass) {
    case typelib_TypeClass_INTERFACE_ATTRIBUTE:
        setter = itd->pMapMemberIndexToFunctionIndex[memberId] != functionId;
            // pMapMemberIndexToFunctionIndex contains function index of
            // attribute getter
        if (setter) {
            inArgs.push_back(
                unmarshal.readValue(
                    css::uno::TypeDescription(
                        reinterpret_cast<
                            typelib_InterfaceAttributeTypeDescription * >(
                                memberTd.get())->
                        pAttributeTypeRef)));
        }
        break;
    case typelib_TypeClass_INTERFACE_METHOD:
        {
            typelib_InterfaceMethodTypeDescription * mtd =
                reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
                    memberTd.get());
            for (sal_Int32 i = 0; i != mtd->nParams; ++i) {
                if (mtd->pParams[i].bIn) {
                    inArgs.push_back(
                        unmarshal.readValue(
                            css::uno::TypeDescription(
                                mtd->pParams[i].pTypeRef)));
                }
            }
            break;
        }
    default:
        OSL_ASSERT(false); // this cannot happen
        break;
    }
    bridge_->incrementCalls(
        !protProps && functionId != SPECIAL_FUNCTION_ID_RELEASE);
    if (protProps) {
        switch (functionId) {
        case SPECIAL_FUNCTION_ID_REQUEST_CHANGE:
            bridge_->handleRequestChangeRequest(tid, inArgs);
            break;
        case SPECIAL_FUNCTION_ID_COMMIT_CHANGE:
            bridge_->handleCommitChangeRequest(tid, inArgs);
            break;
        default:
            throw css::uno::RuntimeException(
                rtl::OUString(
                    RTL_CONSTASCII_USTRINGPARAM(
                        "URP: request message with UrpProtocolProperties OID"
                        " and unknown function ID received")),
                css::uno::Reference< css::uno::XInterface >());
        }
    } else {
        css::uno::UnoInterfaceReference obj;
        switch (functionId) {
        case SPECIAL_FUNCTION_ID_QUERY_INTERFACE:
            obj = bridge_->findStub(oid, type);
            if (!obj.is()) {
                OSL_ASSERT(
                    inArgs.size() == 1
                    && inArgs[0].getType().equals(
                        css::uno::TypeDescription(
                            cppu::UnoType< css::uno::Type >::get())));
                if (!(type.equals(
                          css::uno::TypeDescription(
                              cppu::UnoType<
                                  css::uno::Reference<
                                      css::uno::XInterface > >::get()))
                      && (css::uno::TypeDescription(
                              *static_cast<
                                  typelib_TypeDescriptionReference ** >(
                                      inArgs[0].getValue(inArgs[0].getType()))).
                          equals(
                              css::uno::TypeDescription(
                                  cppu::UnoType<
                                      css::uno::Reference<
                                          css::uno::XInterface > >::get())))))
                {
                    throw css::uno::RuntimeException(
                        rtl::OUString(
                            RTL_CONSTASCII_USTRINGPARAM(
                                "URP: queryInterface request message with"
                                " unknown OID received")),
                        css::uno::Reference< css::uno::XInterface >());
                }
            }
            break;
        case SPECIAL_FUNCTION_ID_RESERVED:
            throw css::uno::RuntimeException(
                rtl::OUString(
                    RTL_CONSTASCII_USTRINGPARAM(
                        "URP: request message with unknown function ID 1"
                        " received")),
                css::uno::Reference< css::uno::XInterface >());
        case SPECIAL_FUNCTION_ID_RELEASE:
            break;
        default:
            obj = bridge_->findStub(oid, type);
            if (!obj.is()) {
                throw css::uno::RuntimeException(
                    rtl::OUString(
                        RTL_CONSTASCII_USTRINGPARAM(
                            "URP: request message with unknown OID received")),
                    css::uno::Reference< css::uno::XInterface >());
            }
            break;
        }
        std::auto_ptr< IncomingRequest > req(
            new IncomingRequest(
                bridge_, tid, oid, obj, type, functionId, synchronous, memberTd,
                setter, inArgs, ccMode, cc));
        if (synchronous) {
            bridge_->incrementActiveCalls();
        }
        uno_threadpool_putJob(
            bridge_->getThreadPool(), tid.getHandle(), req.get(), &request,
            !synchronous);
        req.release();
    }
}

void Reader::readReplyMessage(Unmarshal & unmarshal, sal_uInt8 flags1) {
    rtl::ByteSequence tid(getTid(unmarshal, (flags1 & 0x08) != 0));
        // bit 3: NEWTID
    lastTid_ = tid;
    OutgoingRequest req(bridge_->lastOutgoingRequest(tid));
    bool exc = (flags1 & 0x20) != 0; // bit 5: EXCEPTION
    BinaryAny ret;
    std::vector< BinaryAny > outArgs;
    if (exc) {
        ret = unmarshal.readValue(
            css::uno::TypeDescription(cppu::UnoType< css::uno::Any >::get()));
        if (!typelib_typedescription_isAssignableFrom(
                (css::uno::TypeDescription(
                    cppu::UnoType< css::uno::RuntimeException >::get()).
                 get()),
                ret.getType().get()))
        {
            sal_Int32 n = 0;
            typelib_TypeDescriptionReference ** p = 0;
            switch (req.member.get()->eTypeClass) {
            case typelib_TypeClass_INTERFACE_ATTRIBUTE:
                {
                    typelib_InterfaceAttributeTypeDescription * atd =
                        reinterpret_cast<
                            typelib_InterfaceAttributeTypeDescription * >(
                                req.member.get());
                    n = req.setter ? atd->nSetExceptions : atd->nGetExceptions;
                    p = req.setter
                        ? atd->ppSetExceptions : atd->ppGetExceptions;
                    break;
                }
            case typelib_TypeClass_INTERFACE_METHOD:
                {
                    typelib_InterfaceMethodTypeDescription * mtd =
                        reinterpret_cast<
                            typelib_InterfaceMethodTypeDescription * >(
                                req.member.get());
                    n = mtd->nExceptions;
                    p = mtd->ppExceptions;
                    break;
                }
            default:
                OSL_ASSERT(false); // this cannot happen
                break;
            }
            bool ok = false;
            for (sal_Int32 i = 0; i != n; ++i) {
                if (typelib_typedescriptionreference_isAssignableFrom(
                        p[i],
                        reinterpret_cast< typelib_TypeDescriptionReference * >(
                            ret.getType().get())))
                {
                    ok = true;
                    break;
                }
            }
            if (!ok) {
                throw css::uno::RuntimeException(
                    rtl::OUString(
                        RTL_CONSTASCII_USTRINGPARAM(
                            "URP: reply message with bad exception type"
                            " received")),
                    css::uno::Reference< css::uno::XInterface >());
            }
        }
    } else {
        switch (req.member.get()->eTypeClass) {
        case typelib_TypeClass_INTERFACE_ATTRIBUTE:
            if (!req.setter) {
                ret = unmarshal.readValue(
                    css::uno::TypeDescription(
                        reinterpret_cast<
                            typelib_InterfaceAttributeTypeDescription * >(
                                req.member.get())->
                        pAttributeTypeRef));
            }
            break;
        case typelib_TypeClass_INTERFACE_METHOD:
            {
                typelib_InterfaceMethodTypeDescription * mtd =
                    reinterpret_cast<
                        typelib_InterfaceMethodTypeDescription * >(
                            req.member.get());
                ret = unmarshal.readValue(
                    css::uno::TypeDescription(mtd->pReturnTypeRef));
                for (sal_Int32 i = 0; i != mtd->nParams; ++i) {
                    if (mtd->pParams[i].bOut) {
                        outArgs.push_back(
                            unmarshal.readValue(
                                css::uno::TypeDescription(
                                    mtd->pParams[i].pTypeRef)));
                    }
                }
                break;
            }
        default:
            OSL_ASSERT(false); // this cannot happen
            break;
        }
    }
    switch (req.kind) {
    case OutgoingRequest::KIND_NORMAL:
        {
            std::auto_ptr< IncomingReply > resp(
                new IncomingReply(exc, ret, outArgs));
            uno_threadpool_putJob(
                bridge_->getThreadPool(), tid.getHandle(), resp.get(), 0,
                false);
            resp.release();
            break;
        }
    case OutgoingRequest::KIND_REQUEST_CHANGE:
        OSL_ASSERT(outArgs.empty());
        bridge_->handleRequestChangeReply(exc, ret);
        break;
    case OutgoingRequest::KIND_COMMIT_CHANGE:
        OSL_ASSERT(outArgs.empty());
        bridge_->handleCommitChangeReply(exc, ret);
        break;
    default:
        OSL_ASSERT(false); // this cannot happen
        break;
    }
}

rtl::ByteSequence Reader::getTid(Unmarshal & unmarshal, bool newTid) const {
    if (newTid) {
        return unmarshal.readTid();
    }
    if (lastTid_.getLength() == 0) {
        throw css::uno::RuntimeException(
            rtl::OUString(
                RTL_CONSTASCII_USTRINGPARAM(
                    "URP: message with NEWTID received when last TID has not"
                    " yet been set")),
            css::uno::Reference< css::uno::XInterface >());
    }
    return lastTid_;
}

}
