/*
 * 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 <log4cxx/helpers/messagebuffer.h>
#include <log4cxx/helpers/transcoder.h>

using namespace log4cxx::helpers;

static bool gMessageBufferUseStaticStream = false;

namespace log4cxx
{
namespace helpers
{
void MessageBufferUseStaticStream()
{
    gMessageBufferUseStaticStream = true;
}
}
}

template <typename T>
void ResetStream(std::basic_ostringstream<T>& stream)
{
    stream.seekp(0);
    stream.str(std::basic_string<T>());
    stream.clear();
}

CharMessageBuffer::CharMessageBuffer() : stream(0)
{

#if defined(STATIC_STRINGSTREAM)

    if (gMessageBufferUseStaticStream)
    {
        thread_local static char ossBuf[8192];
        thread_local static std::basic_ostringstream<char> sStream;
        thread_local static bool inited = false;

        if (!inited)
        {
            inited = true;
            sStream.rdbuf()->pubsetbuf(ossBuf, 8192);

            ResetStream(sStream);
        }

        stream = &sStream;
    }

#endif
}

CharMessageBuffer::~CharMessageBuffer()
{
    if (!gMessageBufferUseStaticStream)
    {
        delete stream;
    }
}

CharMessageBuffer& CharMessageBuffer::operator<<(const std::basic_string<char>& msg)
{
    if (stream == 0)
    {
        buf.append(msg);
    }
    else
    {
        *stream << msg;
    }

    return *this;
}

CharMessageBuffer& CharMessageBuffer::operator<<(const char* msg)
{
    const char* actualMsg = msg;

    if (actualMsg == 0)
    {
        actualMsg = "null";
    }

    if (stream == 0)
    {
        buf.append(actualMsg);
    }
    else
    {
        *stream << actualMsg;
    }

    return *this;
}
CharMessageBuffer& CharMessageBuffer::operator<<(char* msg)
{
    return operator<<((const char*) msg);
}

CharMessageBuffer& CharMessageBuffer::operator<<(const char msg)
{
    if (stream == 0)
    {
        buf.append(1, msg);
    }
    else
    {
        buf.assign(1, msg);
        *stream << buf;
    }

    return *this;
}

CharMessageBuffer::operator std::basic_ostream<char>& ()
{
    if (stream == 0)
    {
        stream = new std::basic_ostringstream<char>();

        if (!buf.empty())
        {
            *stream << buf;
        }
    }

    return *stream;
}

const std::basic_string<char>& CharMessageBuffer::str(std::basic_ostream<char>&)
{
    buf = stream->str();

    ResetStream(*stream);

    return buf;
}

const std::basic_string<char>& CharMessageBuffer::str(CharMessageBuffer&)
{
    return buf;
}

bool CharMessageBuffer::hasStream() const
{
    return (stream != 0);
}

std::ostream& CharMessageBuffer::operator<<(ios_base_manip manip)
{
    std::ostream& s = *this;
    (*manip)(s);
    return s;
}

std::ostream& CharMessageBuffer::operator<<(bool val)
{
    return ((std::ostream&) * this).operator << (val);
}
std::ostream& CharMessageBuffer::operator<<(short val)
{
    return ((std::ostream&) * this).operator << (val);
}
std::ostream& CharMessageBuffer::operator<<(int val)
{
    return ((std::ostream&) * this).operator << (val);
}
std::ostream& CharMessageBuffer::operator<<(unsigned int val)
{
    return ((std::ostream&) * this).operator << (val);
}
std::ostream& CharMessageBuffer::operator<<(long val)
{
    return ((std::ostream&) * this).operator << (val);
}
std::ostream& CharMessageBuffer::operator<<(unsigned long val)
{
    return ((std::ostream&) * this).operator << (val);
}
std::ostream& CharMessageBuffer::operator<<(float val)
{
    return ((std::ostream&) * this).operator << (val);
}
std::ostream& CharMessageBuffer::operator<<(double val)
{
    return ((std::ostream&) * this).operator << (val);
}
std::ostream& CharMessageBuffer::operator<<(long double val)
{
    return ((std::ostream&) * this).operator << (val);
}
std::ostream& CharMessageBuffer::operator<<(void* val)
{
    return ((std::ostream&) * this).operator << (val);
}


#if LOG4CXX_WCHAR_T_API
WideMessageBuffer::WideMessageBuffer() : stream(0)
{

#if defined(STATIC_STRINGSTREAM)

    if (gMessageBufferUseStaticStream)
    {
        thread_local static wchar_t ossBuf[8192];
        thread_local static std::basic_ostringstream<wchar_t> sStream;
        thread_local static bool inited = false;

        if (!inited)
        {
            inited = true;
            sStream.rdbuf()->pubsetbuf(ossBuf, 8192);

            ResetStream(sStream);
        }

        stream = &sStream;
    }

#endif
}

WideMessageBuffer::~WideMessageBuffer()
{
    if (!gMessageBufferUseStaticStream)
    {
        delete stream;
    }
}

WideMessageBuffer& WideMessageBuffer::operator<<(const std::basic_string<wchar_t>& msg)
{
    if (stream == 0)
    {
        buf.append(msg);
    }
    else
    {
        *stream << msg;
    }

    return *this;
}

WideMessageBuffer& WideMessageBuffer::operator<<(const wchar_t* msg)
{
    const wchar_t* actualMsg = msg;

    if (actualMsg == 0)
    {
        actualMsg = L"null";
    }

    if (stream == 0)
    {
        buf.append(actualMsg);
    }
    else
    {
        *stream << actualMsg;
    }

    return *this;
}

WideMessageBuffer& WideMessageBuffer::operator<<(wchar_t* msg)
{
    return operator<<((const wchar_t*) msg);
}

WideMessageBuffer& WideMessageBuffer::operator<<(const wchar_t msg)
{
    if (stream == 0)
    {
        buf.append(1, msg);
    }
    else
    {
        buf.assign(1, msg);
        *stream << buf;
    }

    return *this;
}

WideMessageBuffer::operator std::basic_ostream<wchar_t>& ()
{
    if (stream == 0)
    {
        stream = new std::basic_ostringstream<wchar_t>();

        if (!buf.empty())
        {
            *stream << buf;
        }
    }

    return *stream;
}

const std::basic_string<wchar_t>& WideMessageBuffer::str(std::basic_ostream<wchar_t>&)
{
    buf = stream->str();

    ResetStream(*stream);

    return buf;
}

const std::basic_string<wchar_t>& WideMessageBuffer::str(WideMessageBuffer&)
{
    return buf;
}

bool WideMessageBuffer::hasStream() const
{
    return (stream != 0);
}

std::basic_ostream<wchar_t>& WideMessageBuffer::operator<<(ios_base_manip manip)
{
    std::basic_ostream<wchar_t>& s = *this;
    (*manip)(s);
    return s;
}

std::basic_ostream<wchar_t>& WideMessageBuffer::operator<<(bool val)
{
    return ((std::basic_ostream<wchar_t>&) * this).operator << (val);
}
std::basic_ostream<wchar_t>& WideMessageBuffer::operator<<(short val)
{
    return ((std::basic_ostream<wchar_t>&) * this).operator << (val);
}
std::basic_ostream<wchar_t>& WideMessageBuffer::operator<<(int val)
{
    return ((std::basic_ostream<wchar_t>&) * this).operator << (val);
}
std::basic_ostream<wchar_t>& WideMessageBuffer::operator<<(unsigned int val)
{
    return ((std::basic_ostream<wchar_t>&) * this).operator << (val);
}
std::basic_ostream<wchar_t>& WideMessageBuffer::operator<<(long val)
{
    return ((std::basic_ostream<wchar_t>&) * this).operator << (val);
}
std::basic_ostream<wchar_t>& WideMessageBuffer::operator<<(unsigned long val)
{
    return ((std::basic_ostream<wchar_t>&) * this).operator << (val);
}
std::basic_ostream<wchar_t>& WideMessageBuffer::operator<<(float val)
{
    return ((std::basic_ostream<wchar_t>&) * this).operator << (val);
}
std::basic_ostream<wchar_t>& WideMessageBuffer::operator<<(double val)
{
    return ((std::basic_ostream<wchar_t>&) * this).operator << (val);
}
std::basic_ostream<wchar_t>& WideMessageBuffer::operator<<(long double val)
{
    return ((std::basic_ostream<wchar_t>&) * this).operator << (val);
}
std::basic_ostream<wchar_t>& WideMessageBuffer::operator<<(void* val)
{
    return ((std::basic_ostream<wchar_t>&) * this).operator << (val);
}


MessageBuffer::MessageBuffer()  : wbuf(0)
#if LOG4CXX_UNICHAR_API || LOG4CXX_CFSTRING_API
    , ubuf(0)
#endif
{
}

MessageBuffer::~MessageBuffer()
{
    delete wbuf;
#if LOG4CXX_UNICHAR_API || LOG4CXX_CFSTRING_API
    delete ubuf;
#endif
}

bool MessageBuffer::hasStream() const
{
    bool retval = cbuf.hasStream() || (wbuf != 0 && wbuf->hasStream());
#if LOG4CXX_UNICHAR_API || LOG4CXX_CFSTRING_API
    retval = retval || (ubuf != 0 && ubuf->hasStream());
#endif
    return retval;
}

std::ostream& MessageBuffer::operator<<(ios_base_manip manip)
{
    std::ostream& s = *this;
    (*manip)(s);
    return s;
}

MessageBuffer::operator std::ostream& ()
{
    return (std::ostream&) cbuf;
}

CharMessageBuffer& MessageBuffer::operator<<(const std::string& msg)
{
    return cbuf.operator << (msg);
}

CharMessageBuffer& MessageBuffer::operator<<(const char* msg)
{
    return cbuf.operator << (msg);
}
CharMessageBuffer& MessageBuffer::operator<<(char* msg)
{
    return cbuf.operator << ((const char*) msg);
}

CharMessageBuffer& MessageBuffer::operator<<(const char msg)
{
    return cbuf.operator << (msg);
}

const std::string& MessageBuffer::str(CharMessageBuffer& buf)
{
    return cbuf.str(buf);
}

const std::string& MessageBuffer::str(std::ostream& os)
{
    return cbuf.str(os);
}

WideMessageBuffer& MessageBuffer::operator<<(const std::wstring& msg)
{
    wbuf = new WideMessageBuffer();
    return (*wbuf) << msg;
}

WideMessageBuffer& MessageBuffer::operator<<(const wchar_t* msg)
{
    wbuf = new WideMessageBuffer();
    return (*wbuf) << msg;
}
WideMessageBuffer& MessageBuffer::operator<<(wchar_t* msg)
{
    wbuf = new WideMessageBuffer();
    return (*wbuf) << (const wchar_t*) msg;
}

WideMessageBuffer& MessageBuffer::operator<<(const wchar_t msg)
{
    wbuf = new WideMessageBuffer();
    return (*wbuf) << msg;
}

const std::wstring& MessageBuffer::str(WideMessageBuffer& buf)
{
    return wbuf->str(buf);
}

const std::wstring& MessageBuffer::str(std::basic_ostream<wchar_t>& os)
{
    return wbuf->str(os);
}

std::ostream& MessageBuffer::operator<<(bool val)
{
    return cbuf.operator << (val);
}
std::ostream& MessageBuffer::operator<<(short val)
{
    return cbuf.operator << (val);
}
std::ostream& MessageBuffer::operator<<(int val)
{
    return cbuf.operator << (val);
}
std::ostream& MessageBuffer::operator<<(unsigned int val)
{
    return cbuf.operator << (val);
}
std::ostream& MessageBuffer::operator<<(long val)
{
    return cbuf.operator << (val);
}
std::ostream& MessageBuffer::operator<<(unsigned long val)
{
    return cbuf.operator << (val);
}
std::ostream& MessageBuffer::operator<<(float val)
{
    return cbuf.operator << (val);
}
std::ostream& MessageBuffer::operator<<(double val)
{
    return cbuf.operator << (val);
}
std::ostream& MessageBuffer::operator<<(long double val)
{
    return cbuf.operator << (val);
}
std::ostream& MessageBuffer::operator<<(void* val)
{
    return cbuf.operator << (val);
}


#endif


#if LOG4CXX_UNICHAR_API || LOG4CXX_CFSTRING_API
UniCharMessageBuffer& MessageBuffer::operator<<(const std::basic_string<log4cxx::UniChar>& msg)
{
    ubuf = new UniCharMessageBuffer();
    return (*ubuf) << msg;
}

UniCharMessageBuffer& MessageBuffer::operator<<(const log4cxx::UniChar* msg)
{
    ubuf = new UniCharMessageBuffer();
    return (*ubuf) << msg;
}
UniCharMessageBuffer& MessageBuffer::operator<<(log4cxx::UniChar* msg)
{
    ubuf = new UniCharMessageBuffer();
    return (*ubuf) << (const log4cxx::UniChar*) msg;
}

UniCharMessageBuffer& MessageBuffer::operator<<(const log4cxx::UniChar msg)
{
    ubuf = new UniCharMessageBuffer();
    return (*ubuf) << msg;
}

const std::basic_string<log4cxx::UniChar>& MessageBuffer::str(UniCharMessageBuffer& buf)
{
    return ubuf->str(buf);
}

const std::basic_string<log4cxx::UniChar>& MessageBuffer::str(std::basic_ostream<log4cxx::UniChar>& os)
{
    return ubuf->str(os);
}


UniCharMessageBuffer::UniCharMessageBuffer() : stream(0)
{

#if defined(STATIC_STRINGSTREAM)

    if (gMessageBufferUseStaticStream)
    {
        thread_local static log4cxx::UniChar ossBuf[8192];
        thread_local static std::basic_ostringstream<log4cxx::UniChar> sStream;
        thread_local static bool inited = false;

        if (!inited)
        {
            inited = true;
            sStream.rdbuf()->pubsetbuf(ossBuf, 8192);

            ResetStream(sStream);
        }

        stream = &sStream;
    }

#endif
}

UniCharMessageBuffer::~UniCharMessageBuffer()
{
    if (!gMessageBufferUseStaticStream)
    {
        delete stream;
    }
}


UniCharMessageBuffer& UniCharMessageBuffer::operator<<(const std::basic_string<log4cxx::UniChar>& msg)
{
    if (stream == 0)
    {
        buf.append(msg);
    }
    else
    {
        *stream << buf;
    }

    return *this;
}

UniCharMessageBuffer& UniCharMessageBuffer::operator<<(const log4cxx::UniChar* msg)
{
    const log4cxx::UniChar* actualMsg = msg;
    static log4cxx::UniChar nullLiteral[] = { 0x6E, 0x75, 0x6C, 0x6C, 0};

    if (actualMsg == 0)
    {
        actualMsg = nullLiteral;
    }

    if (stream == 0)
    {
        buf.append(actualMsg);
    }
    else
    {
        *stream << actualMsg;
    }

    return *this;
}

UniCharMessageBuffer& UniCharMessageBuffer::operator<<(log4cxx::UniChar* msg)
{
    return operator<<((const log4cxx::UniChar*) msg);
}

UniCharMessageBuffer& UniCharMessageBuffer::operator<<(const log4cxx::UniChar msg)
{
    if (stream == 0)
    {
        buf.append(1, msg);
    }
    else
    {
        *stream << msg;
    }

    return *this;
}

UniCharMessageBuffer::operator UniCharMessageBuffer::uostream& ()
{
    if (stream == 0)
    {
        stream = new std::basic_ostringstream<UniChar>();

        if (!buf.empty())
        {
            *stream << buf;
        }
    }

    return *stream;
}

const std::basic_string<log4cxx::UniChar>& UniCharMessageBuffer::str(UniCharMessageBuffer::uostream&)
{
    buf = stream->str();
    ResetStream(*stream);
    return buf;
}

const std::basic_string<log4cxx::UniChar>& UniCharMessageBuffer::str(UniCharMessageBuffer&)
{
    return buf;
}

bool UniCharMessageBuffer::hasStream() const
{
    return (stream != 0);
}

UniCharMessageBuffer::uostream& UniCharMessageBuffer::operator<<(ios_base_manip manip)
{
    UniCharMessageBuffer::uostream& s = *this;
    (*manip)(s);
    return s;
}

UniCharMessageBuffer::uostream& UniCharMessageBuffer::operator<<(bool val)
{
    return ((UniCharMessageBuffer::uostream&) * this).operator << (val);
}
UniCharMessageBuffer::uostream& UniCharMessageBuffer::operator<<(short val)
{
    return ((UniCharMessageBuffer::uostream&) * this).operator << (val);
}
UniCharMessageBuffer::uostream& UniCharMessageBuffer::operator<<(int val)
{
    return ((UniCharMessageBuffer::uostream&) * this).operator << (val);
}
UniCharMessageBuffer::uostream& UniCharMessageBuffer::operator<<(unsigned int val)
{
    return ((UniCharMessageBuffer::uostream&) * this).operator << (val);
}
UniCharMessageBuffer::uostream& UniCharMessageBuffer::operator<<(long val)
{
    return ((UniCharMessageBuffer::uostream&) * this).operator << (val);
}
UniCharMessageBuffer::uostream& UniCharMessageBuffer::operator<<(unsigned long val)
{
    return ((UniCharMessageBuffer::uostream&) * this).operator << (val);
}
UniCharMessageBuffer::uostream& UniCharMessageBuffer::operator<<(float val)
{
    return ((UniCharMessageBuffer::uostream&) * this).operator << (val);
}
UniCharMessageBuffer::uostream& UniCharMessageBuffer::operator<<(double val)
{
    return ((UniCharMessageBuffer::uostream&) * this).operator << (val);
}
UniCharMessageBuffer::uostream& UniCharMessageBuffer::operator<<(long double val)
{
    return ((UniCharMessageBuffer::uostream&) * this).operator << (val);
}
UniCharMessageBuffer::uostream& UniCharMessageBuffer::operator<<(void* val)
{
    return ((UniCharMessageBuffer::uostream&) * this).operator << (val);
}



#endif

#if LOG4CXX_CFSTRING_API
#include <CoreFoundation/CFString.h>
#include <vector>

UniCharMessageBuffer& UniCharMessageBuffer::operator<<(const CFStringRef& msg)
{
    const log4cxx::UniChar* chars = CFStringGetCharactersPtr(msg);

    if (chars != 0)
    {
        return operator<<(chars);
    }
    else
    {
        size_t length = CFStringGetLength(msg);
        std::vector<log4cxx::UniChar> tmp(length);
        CFStringGetCharacters(msg, CFRangeMake(0, length), &tmp[0]);

        if (stream)
        {
            std::basic_string<UniChar> s(&tmp[0], tmp.size());
            *stream << s;
        }
        else
        {
            buf.append(&tmp[0], tmp.size());
        }
    }

    return *this;
}


UniCharMessageBuffer& MessageBuffer::operator<<(const CFStringRef& msg)
{
    ubuf = new UniCharMessageBuffer();
    return (*ubuf) << msg;
}
#endif

