/**************************************************************
 * 
 * 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.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_comphelper.hxx"

#include "comphelper/anytostring.hxx"
#include "osl/diagnose.h"
#include "rtl/ustrbuf.hxx"
#include "typelib/typedescription.h"
#include "com/sun/star/lang/XServiceInfo.hpp"

using namespace ::com::sun::star;

namespace comphelper {
namespace {

void appendTypeError(
    rtl::OUStringBuffer & buf, typelib_TypeDescriptionReference * typeRef )
{
    buf.appendAscii(
        RTL_CONSTASCII_STRINGPARAM("<cannot get type description of type ") );
    buf.append( rtl::OUString::unacquired( &typeRef->pTypeName ) );
    buf.append( static_cast< sal_Unicode >('>') );
}

inline void appendChar( rtl::OUStringBuffer & buf, sal_Unicode c )
{
    if (c < ' ' || c > '~') {
        buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\\X") );
        rtl::OUString const s(
            rtl::OUString::valueOf( static_cast< sal_Int32 >(c), 16 ) );
        for ( sal_Int32 f = 4 - s.getLength(); f > 0; --f )
            buf.append( static_cast< sal_Unicode >('0') );
        buf.append( s );
    }
    else {
        buf.append( c );
    }
}

//------------------------------------------------------------------------------
void appendValue( rtl::OUStringBuffer & buf,
                  void const * val, typelib_TypeDescriptionReference * typeRef,
                  bool prependType )
{
    if (typeRef->eTypeClass == typelib_TypeClass_VOID) {
        buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("void") );
        return;
    }
    OSL_ASSERT( val != 0 );

    if (prependType &&
        typeRef->eTypeClass != typelib_TypeClass_STRING &&
        typeRef->eTypeClass != typelib_TypeClass_CHAR &&
        typeRef->eTypeClass != typelib_TypeClass_BOOLEAN)
    {
        buf.append( static_cast< sal_Unicode >('(') );
        buf.append( rtl::OUString::unacquired( &typeRef->pTypeName ) );
        buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(") ") );
    }
    
    switch (typeRef->eTypeClass) {
    case typelib_TypeClass_INTERFACE: {
        buf.append( static_cast<sal_Unicode>('@') );
        buf.append( reinterpret_cast< sal_Int64 >(
                        *static_cast< void * const * >(val) ), 16 );
        uno::Reference< lang::XServiceInfo > xServiceInfo(
            *static_cast< uno::XInterface * const * >(val),
            uno::UNO_QUERY );
        if (xServiceInfo.is()) {
            buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
                                 " (ImplementationName = \"") );
            buf.append( xServiceInfo->getImplementationName() );
            buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\")") );
        }
        break;
    }
    case typelib_TypeClass_STRUCT:
    case typelib_TypeClass_EXCEPTION: {
        buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") );
        typelib_TypeDescription * typeDescr = 0;
        typelib_typedescriptionreference_getDescription( &typeDescr, typeRef );
        if (typeDescr == 0 || !typelib_typedescription_complete( &typeDescr )) {
            appendTypeError( buf, typeRef );
        }
        else {
            typelib_CompoundTypeDescription * compType =
                reinterpret_cast< typelib_CompoundTypeDescription * >(
                    typeDescr );
            sal_Int32 nDescr = compType->nMembers;
            
            if (compType->pBaseTypeDescription) {
                appendValue(
                    buf, val, reinterpret_cast<
                    typelib_TypeDescription * >(
                        compType->pBaseTypeDescription)->pWeakRef, false );
                if (nDescr > 0)
                    buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
            }
            
            typelib_TypeDescriptionReference ** ppTypeRefs =
                compType->ppTypeRefs;
            sal_Int32 * memberOffsets = compType->pMemberOffsets;
            rtl_uString ** ppMemberNames = compType->ppMemberNames;
            
            for ( sal_Int32 nPos = 0; nPos < nDescr; ++nPos )
            {
                buf.append( ppMemberNames[ nPos ] );
                buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" = ") );
                typelib_TypeDescription * memberType = 0;
                TYPELIB_DANGER_GET( &memberType, ppTypeRefs[ nPos ] );
                if (memberType == 0) {
                    appendTypeError( buf, ppTypeRefs[ nPos ] );
                }
                else {
                    appendValue( buf,
                                 static_cast< char const * >(
                                     val ) + memberOffsets[ nPos ],
                                 memberType->pWeakRef, true );
                    TYPELIB_DANGER_RELEASE( memberType );
                }
                if (nPos < (nDescr - 1))
                    buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
            }
        }
        buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") );
        if (typeDescr != 0)
            typelib_typedescription_release( typeDescr );
        break;
    }
    case typelib_TypeClass_SEQUENCE: {
        typelib_TypeDescription * typeDescr = 0;
        TYPELIB_DANGER_GET( &typeDescr, typeRef );
        if (typeDescr == 0) {
            appendTypeError( buf,typeRef );
        }
        else {
            typelib_TypeDescriptionReference * elementTypeRef =
                reinterpret_cast<
                typelib_IndirectTypeDescription * >(typeDescr)->pType;
            typelib_TypeDescription * elementTypeDescr = 0;
            TYPELIB_DANGER_GET( &elementTypeDescr, elementTypeRef );
            if (elementTypeDescr == 0)
            {
                appendTypeError( buf, elementTypeRef );
            }
            else
            {
                sal_Int32 nElementSize = elementTypeDescr->nSize;
                uno_Sequence * seq =
                    *static_cast< uno_Sequence * const * >(val);
                sal_Int32 nElements = seq->nElements;
                
                if (nElements > 0)
                {
                    buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") );
                    char const * pElements = seq->elements;
                    for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
                    {
                        appendValue(
                            buf, pElements + (nElementSize * nPos),
                            elementTypeDescr->pWeakRef, false );
                        if (nPos < (nElements - 1))
                            buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
                    }
                    buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") );
                }
                else
                {
                    buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{}") );
                }
                TYPELIB_DANGER_RELEASE( elementTypeDescr );
            }
            TYPELIB_DANGER_RELEASE( typeDescr );
        }
        break;
    }
    case typelib_TypeClass_ANY: {
        buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") );
        uno_Any const * pAny = static_cast< uno_Any const * >(val);
        appendValue( buf, pAny->pData, pAny->pType, true );
        buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") );
        break;
    }
    case typelib_TypeClass_TYPE:
        buf.append( (*reinterpret_cast<
                     typelib_TypeDescriptionReference * const * >(val)
                        )->pTypeName );
        break;
    case typelib_TypeClass_STRING: {
        buf.append( static_cast< sal_Unicode >('\"') );
        rtl::OUString const & str = rtl::OUString::unacquired(
            static_cast< rtl_uString * const * >(val) );
        sal_Int32 len = str.getLength();
        for ( sal_Int32 pos = 0; pos < len; ++pos )
        {
            sal_Unicode c = str[ pos ];
            if (c == '\"')
                buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\\\"") );
            else if (c == '\\')
                buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\\\\") );
            else
                appendChar( buf, c );
        }
        buf.append( static_cast< sal_Unicode >('\"') );
        break;
    }
    case typelib_TypeClass_ENUM: {
        typelib_TypeDescription * typeDescr = 0;
        typelib_typedescriptionreference_getDescription( &typeDescr, typeRef );
        if (typeDescr == 0 || !typelib_typedescription_complete( &typeDescr )) {
            appendTypeError( buf, typeRef );
        }
        else
        {
            sal_Int32 * pValues =
                reinterpret_cast< typelib_EnumTypeDescription * >(
                    typeDescr )->pEnumValues;
            sal_Int32 nPos = reinterpret_cast< typelib_EnumTypeDescription * >(
                typeDescr )->nEnumValues;
            while (nPos--)
            {
                if (pValues[ nPos ] == *static_cast< int const * >(val))
                    break;
            }
            if (nPos >= 0)
            {
                buf.append( reinterpret_cast< typelib_EnumTypeDescription * >(
                                typeDescr )->ppEnumNames[ nPos ] );
            }
            else
            {
                buf.appendAscii(
                    RTL_CONSTASCII_STRINGPARAM("?unknown enum value?") );
            }
        }
        if (typeDescr != 0)
            typelib_typedescription_release( typeDescr );
        break;
    }
    case typelib_TypeClass_BOOLEAN:
        if (*static_cast< sal_Bool const * >(val) != sal_False)
            buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("true") );
        else
            buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("false") );
        break;
    case typelib_TypeClass_CHAR: {
        buf.append( static_cast< sal_Unicode >('\'') );
        sal_Unicode c = *static_cast< sal_Unicode const * >(val);
        if (c == '\'')
            buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\\\'") );
        else if (c == '\\')
            buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\\\\") );
        else
            appendChar( buf, c );
        buf.append( static_cast< sal_Unicode >('\'') );
        break;
    }
    case typelib_TypeClass_FLOAT:
        buf.append( *static_cast< float const * >(val) );
        break;
    case typelib_TypeClass_DOUBLE:
        buf.append( *static_cast< double const * >(val) );
        break;
    case typelib_TypeClass_BYTE:
        buf.append( static_cast< sal_Int32 >(
                        *static_cast< sal_Int8 const * >(val) ) );
        break;
    case typelib_TypeClass_SHORT:
        buf.append( static_cast< sal_Int32 >(
                        *static_cast< sal_Int16 const * >(val) ) );
        break;
    case typelib_TypeClass_UNSIGNED_SHORT:
        buf.append( static_cast< sal_Int32 >(
                        *static_cast< sal_uInt16 const * >(val) ) );
        break;
    case typelib_TypeClass_LONG:
        buf.append( *static_cast< sal_Int32 const * >(val) );
        break;
    case typelib_TypeClass_UNSIGNED_LONG:
        buf.append( static_cast< sal_Int64 >(
                        *static_cast< sal_uInt32 const * >(val) ) );
        break;
    case typelib_TypeClass_HYPER:
    case typelib_TypeClass_UNSIGNED_HYPER:
        buf.append( *static_cast< sal_Int64 const * >(val) );
        break;
//     case typelib_TypeClass_UNION:
//     case typelib_TypeClass_ARRAY:
//     case typelib_TypeClass_UNKNOWN:
//     case typelib_TypeClass_SERVICE:
//     case typelib_TypeClass_MODULE:
    default:
        buf.append( static_cast< sal_Unicode >('?') );
        break;
    }
}

} // anon namespace

//==============================================================================
rtl::OUString anyToString( uno::Any const & value )
{
    rtl::OUStringBuffer buf;
    appendValue( buf, value.getValue(), value.getValueTypeRef(), true );
    return buf.makeStringAndClear();
}

} // namespace comphelper

