/*
 *          Copyright Andrey Semashev 2007 - 2015.
 * Distributed under the Boost Software License, Version 1.0.
 *    (See accompanying file LICENSE_1_0.txt or copy at
 *          http://www.boost.org/LICENSE_1_0.txt)
 */
/*!
 * \file   formatter_parser.cpp
 * \author Andrey Semashev
 * \date   07.04.2008
 *
 * \brief  This header is the Boost.Log library implementation, see the library documentation
 *         at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
 */

#ifndef BOOST_LOG_WITHOUT_SETTINGS_PARSERS

#include <map>
#include <string>
#include <sstream>
#include <stdexcept>
#include <boost/assert.hpp>
#include <boost/bind.hpp>
#include <boost/move/core.hpp>
#include <boost/move/utility.hpp>
#include <boost/optional/optional.hpp>
#include <boost/utility/in_place_factory.hpp>
#include <boost/log/expressions/formatter.hpp>
#include <boost/log/attributes/attribute_name.hpp>
#include <boost/log/exceptions.hpp>
#include <boost/log/detail/singleton.hpp>
#include <boost/log/detail/code_conversion.hpp>
#include <boost/log/detail/default_attribute_names.hpp>
#include <boost/log/utility/formatting_ostream.hpp>
#include <boost/log/utility/functional/nop.hpp>
#include <boost/log/utility/setup/formatter_parser.hpp>
#if !defined(BOOST_LOG_NO_THREADS)
#include <boost/log/detail/locks.hpp>
#include <boost/log/detail/light_rw_mutex.hpp>
#endif
#include "parser_utils.hpp"
#include "spirit_encoding.hpp"
#if !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
#include "default_formatter_factory.hpp"
#endif
#include <boost/log/detail/header.hpp>

namespace boost {

BOOST_LOG_OPEN_NAMESPACE

BOOST_LOG_ANONYMOUS_NAMESPACE {

//! The structure contains formatter factories repository
template< typename CharT >
struct formatters_repository :
    public log::aux::lazy_singleton< formatters_repository< CharT > >
{
    //! Base class type
    typedef log::aux::lazy_singleton< formatters_repository< CharT > > base_type;

#if !defined(BOOST_LOG_BROKEN_FRIEND_TEMPLATE_SPECIALIZATIONS)
    friend class log::aux::lazy_singleton< formatters_repository< CharT > >;
#else
    friend class base_type;
#endif

    typedef CharT char_type;
    typedef formatter_factory< char_type > formatter_factory_type;

    //! Attribute name ordering predicate
    struct attribute_name_order
    {
        typedef bool result_type;
        result_type operator() (attribute_name const& left, attribute_name const& right) const
        {
            return left.id() < right.id();
        }
    };

    //! Map of formatter factories
    typedef std::map< attribute_name, shared_ptr< formatter_factory_type >, attribute_name_order > factories_map;


#if !defined(BOOST_LOG_NO_THREADS)
    //! Synchronization mutex
    mutable log::aux::light_rw_mutex m_Mutex;
#endif
    //! The map of formatter factories
    factories_map m_Map;
#if !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
    //! Default factory
    mutable aux::default_formatter_factory< char_type > m_DefaultFactory;
#endif

    //! The method returns the filter factory for the specified attribute name
    formatter_factory_type& get_factory(attribute_name const& name) const
    {
        typename factories_map::const_iterator it = m_Map.find(name);
        if (it != m_Map.end())
        {
            return *it->second;
        }
        else
        {
#if !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
            return m_DefaultFactory;
#else
            BOOST_LOG_THROW_DESCR(setup_error, "No formatter factory registered for attribute " + name.string());
#endif
        }
    }

private:
    formatters_repository()
    {
    }
};

//! Function object for formatter chaining
template< typename CharT, typename SecondT >
struct chained_formatter
{
    typedef void result_type;
    typedef basic_formatter< CharT > formatter_type;
    typedef typename formatter_type::stream_type stream_type;

#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
    explicit chained_formatter(formatter_type&& first, SecondT&& second) :
#else
    template< typename T >
    explicit chained_formatter(BOOST_RV_REF(formatter_type) first, T const& second) :
#endif
        m_first(boost::move(first)), m_second(boost::move(second))
    {
    }

    result_type operator() (record_view const& rec, stream_type& strm) const
    {
        m_first(rec, strm);
        m_second(rec, strm);
    }

private:
    formatter_type m_first;
    SecondT m_second;
};

//! String literal formatter
template< typename CharT >
struct literal_formatter
{
    typedef void result_type;
    typedef CharT char_type;
    typedef std::basic_string< char_type > string_type;
    typedef basic_formatting_ostream< char_type > stream_type;

#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
    explicit literal_formatter(string_type&& str) : m_str(boost::move(str))
#else
    explicit literal_formatter(string_type const& str) : m_str(str)
#endif
    {
    }

    result_type operator() (record_view const& rec, stream_type& strm) const
    {
        strm << m_str;
    }

private:
    const string_type m_str;
};

//! Formatter parsing grammar
template< typename CharT >
class formatter_parser
{
private:
    typedef CharT char_type;
    typedef const char_type* iterator_type;
    typedef std::basic_string< char_type > string_type;
    typedef basic_formatter< char_type > formatter_type;
    typedef boost::log::aux::char_constants< char_type > constants;
    typedef typename log::aux::encoding< char_type >::type encoding;
    typedef log::aux::encoding_specific< encoding > encoding_specific;
    typedef formatter_factory< char_type > formatter_factory_type;
    typedef typename formatter_factory_type::args_map args_map;

private:
    //! The formatter being constructed
    optional< formatter_type > m_Formatter;

    //! Attribute name
    attribute_name m_AttrName;
    //! Formatter factory arguments
    args_map m_FactoryArgs;

    //! Formatter argument name
    mutable string_type m_ArgName;
    //! Argument value
    mutable string_type m_ArgValue;

public:
    //! Constructor
    formatter_parser()
    {
    }

    //! Parses formatter
    void parse(iterator_type& begin, iterator_type end)
    {
        iterator_type p = begin;

        while (p != end)
        {
            // Find the end of a string literal
            iterator_type start = p;
            for (; p != end; ++p)
            {
                char_type c = *p;
                if (c == constants::char_backslash)
                {
                    // We found an escaped character
                    ++p;
                    if (p == end)
                        BOOST_LOG_THROW_DESCR(parse_error, "Invalid escape sequence in the formatter string");
                }
                else if (c == constants::char_percent)
                {
                    // We found an attribute
                    break;
                }
            }

            if (start != p)
                push_string(start, p);

            if (p != end)
            {
                // We found an attribute placeholder
                iterator_type start = constants::trim_spaces_left(++p, end);
                p = constants::scan_attr_placeholder(start, end);
                if (p == end)
                    BOOST_LOG_THROW_DESCR(parse_error, "Invalid attribute placeholder in the formatter string");

                on_attribute_name(start, p);

                p = constants::trim_spaces_left(p, end);
                if (p == end)
                    BOOST_LOG_THROW_DESCR(parse_error, "Invalid attribute placeholder in the formatter string");

                if (*p == constants::char_paren_bracket_left)
                {
                    // We found formatter arguments
                    p = parse_args(constants::trim_spaces_left(++p, end), end);
                    p = constants::trim_spaces_left(p, end);
                    if (p == end)
                        BOOST_LOG_THROW_DESCR(parse_error, "Invalid attribute placeholder in the formatter string");
                }

                if (*p != constants::char_percent)
                    BOOST_LOG_THROW_DESCR(parse_error, "Invalid attribute placeholder in the formatter string");

                ++p;

                push_attr();
            }
        }

        begin = p;
    }

    //! Returns the parsed formatter
    formatter_type get_formatter()
    {
        if (!m_Formatter)
        {
            // This may happen if parser input is an empty string
            return formatter_type(nop());
        }

        return boost::move(m_Formatter.get());
    }

private:
    //! The method parses formatter arguments
    iterator_type parse_args(iterator_type begin, iterator_type end)
    {
        iterator_type p = begin;
        if (p == end)
            BOOST_LOG_THROW_DESCR(parse_error, "Invalid attribute placeholder arguments description in the formatter string");
        if (*p == constants::char_paren_bracket_right)
            return ++p;

        while (true)
        {
            char_type c = *p;

            // Read argument name
            iterator_type start = p;
            if (!encoding::isalpha(*p))
                BOOST_LOG_THROW_DESCR(parse_error, "Placeholder argument name is invalid");
            for (++p; p != end; ++p)
            {
                c = *p;
                if (encoding::isspace(c) || c == constants::char_equal)
                    break;
                if (!encoding::isalnum(c) && c != constants::char_underline)
                    BOOST_LOG_THROW_DESCR(parse_error, "Placeholder argument name is invalid");
            }

            if (start == p)
                BOOST_LOG_THROW_DESCR(parse_error, "Placeholder argument name is empty");

            on_arg_name(start, p);

            p = constants::trim_spaces_left(p, end);
            if (p == end || *p != constants::char_equal)
                BOOST_LOG_THROW_DESCR(parse_error, "Placeholder argument description is not valid");

            // Read argument value
            start = p = constants::trim_spaces_left(++p, end);
            p = constants::parse_operand(p, end, m_ArgValue);
            if (p == start)
                BOOST_LOG_THROW_DESCR(parse_error, "Placeholder argument value is not specified");

            push_arg();

            p = constants::trim_spaces_left(p, end);
            if (p == end)
                BOOST_LOG_THROW_DESCR(parse_error, "Invalid attribute placeholder arguments description in the formatter string");

            c = *p;
            if (c == constants::char_paren_bracket_right)
            {
                break;
            }
            else if (c == constants::char_comma)
            {
                p = constants::trim_spaces_left(++p, end);
                if (p == end)
                    BOOST_LOG_THROW_DESCR(parse_error, "Placeholder argument name is invalid");
            }
            else
            {
                BOOST_LOG_THROW_DESCR(parse_error, "Invalid attribute placeholder arguments description in the formatter string");
            }
        }

        return ++p;
    }

    //! The method is called when an argument name is discovered
    void on_arg_name(iterator_type begin, iterator_type end)
    {
        m_ArgName.assign(begin, end);
    }

    //! The method is called when an argument is filled
    void push_arg()
    {
        m_FactoryArgs[m_ArgName] = m_ArgValue;
        m_ArgName.clear();
        m_ArgValue.clear();
    }

    //! The method is called when an attribute name is discovered
    void on_attribute_name(iterator_type begin, iterator_type end)
    {
        if (begin == end)
            BOOST_LOG_THROW_DESCR(parse_error, "Empty attribute name encountered");

        // For compatibility with Boost.Log v1 we recognize %_% as the message attribute name
        const std::size_t len = end - begin;
        if (std::char_traits< char_type >::length(constants::message_text_keyword()) == len &&
            std::char_traits< char_type >::compare(constants::message_text_keyword(), begin, len) == 0)
        {
            m_AttrName = log::aux::default_attribute_names::message();
        }
        else
        {
            m_AttrName = attribute_name(log::aux::to_narrow(string_type(begin, end)));
        }
    }
    //! The method is called when an attribute is filled
    void push_attr()
    {
        BOOST_ASSERT_MSG(!!m_AttrName, "Attribute name is not set");

        if (m_AttrName == log::aux::default_attribute_names::message())
        {
            // We make a special treatment for the message text formatter
            append_formatter(expressions::aux::message_formatter());
        }
        else
        {
            // Use the factory to create the formatter
            formatters_repository< char_type > const& repo = formatters_repository< char_type >::get();
            formatter_factory_type& factory = repo.get_factory(m_AttrName);
            append_formatter(factory.create_formatter(m_AttrName, m_FactoryArgs));
        }

        // Eventually, clear all the auxiliary data
        m_AttrName = attribute_name();
        m_FactoryArgs.clear();
    }

    //! The method is called when a string literal is discovered
    void push_string(iterator_type begin, iterator_type end)
    {
        string_type s(begin, end);
        constants::translate_escape_sequences(s);
        append_formatter(literal_formatter< char_type >(boost::move(s)));
    }

    //! The method appends a formatter part to the final formatter
    template< typename FormatterT >
    void append_formatter(FormatterT fmt)
    {
        if (!!m_Formatter)
            m_Formatter = boost::in_place(chained_formatter< char_type, FormatterT >(boost::move(m_Formatter.get()), boost::move(fmt)));
        else
            m_Formatter = boost::in_place(boost::move(fmt));
    }

    //  Assignment and copying are prohibited
    BOOST_DELETED_FUNCTION(formatter_parser(formatter_parser const&))
    BOOST_DELETED_FUNCTION(formatter_parser& operator= (formatter_parser const&))
};

} // namespace

//! The function registers a user-defined formatter factory
template< typename CharT >
void register_formatter_factory(attribute_name const& name, shared_ptr< formatter_factory< CharT > > const& factory)
{
    BOOST_ASSERT(!!name);
    BOOST_ASSERT(!!factory);

    formatters_repository< CharT >& repo = formatters_repository< CharT >::get();
    BOOST_LOG_EXPR_IF_MT(log::aux::exclusive_lock_guard< log::aux::light_rw_mutex > lock(repo.m_Mutex);)
    repo.m_Map[name] = factory;
}

//! The function parses a formatter from the string
template< typename CharT >
basic_formatter< CharT > parse_formatter(const CharT* begin, const CharT* end)
{
    typedef CharT char_type;

    formatter_parser< char_type > parser;
    const char_type* p = begin;

    BOOST_LOG_EXPR_IF_MT(formatters_repository< CharT >& repo = formatters_repository< CharT >::get();)
    BOOST_LOG_EXPR_IF_MT(log::aux::shared_lock_guard< log::aux::light_rw_mutex > lock(repo.m_Mutex);)

    parser.parse(p, end);

    return parser.get_formatter();
}

#ifdef BOOST_LOG_USE_CHAR
template BOOST_LOG_SETUP_API
void register_formatter_factory< char >(
    attribute_name const& attr_name, shared_ptr< formatter_factory< char > > const& factory);
template BOOST_LOG_SETUP_API
basic_formatter< char > parse_formatter< char >(const char* begin, const char* end);
#endif // BOOST_LOG_USE_CHAR

#ifdef BOOST_LOG_USE_WCHAR_T
template BOOST_LOG_SETUP_API
void register_formatter_factory< wchar_t >(
    attribute_name const& attr_name, shared_ptr< formatter_factory< wchar_t > > const& factory);
template BOOST_LOG_SETUP_API
basic_formatter< wchar_t > parse_formatter< wchar_t >(const wchar_t* begin, const wchar_t* end);
#endif // BOOST_LOG_USE_WCHAR_T

BOOST_LOG_CLOSE_NAMESPACE // namespace log

} // namespace boost

#include <boost/log/detail/footer.hpp>

#endif // BOOST_LOG_WITHOUT_SETTINGS_PARSERS
