/*=============================================================================
    Copyright (c) 2003 Hartmut Kaiser
    http://spirit.sourceforge.net/

    Use, modification and distribution is subject to 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)
=============================================================================*/
#ifndef BOOST_SPIRIT_SWITCH_IPP
#define BOOST_SPIRIT_SWITCH_IPP

#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/static_assert.hpp>

#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/inc.hpp>
#include <boost/preprocessor/repeat.hpp>
#include <boost/preprocessor/repeat_from_to.hpp>

#include <boost/spirit/home/classic/core/parser.hpp>
#include <boost/spirit/home/classic/core/primitives/primitives.hpp>
#include <boost/spirit/home/classic/core/composite/composite.hpp>
#include <boost/spirit/home/classic/meta/as_parser.hpp>

#include <boost/spirit/home/classic/phoenix/actor.hpp>
#include <boost/spirit/home/classic/phoenix/tuples.hpp>

///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {

BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN

// forward declaration
template <int N, typename ParserT, bool IsDefault> struct case_parser;

///////////////////////////////////////////////////////////////////////////////
namespace impl {

///////////////////////////////////////////////////////////////////////////////
//  parse helper functions
template <typename ParserT, typename ScannerT>
inline typename parser_result<ParserT, ScannerT>::type
delegate_parse(ParserT const &p, ScannerT const &scan,
    typename ScannerT::iterator_t const save)
{
    typedef typename parser_result<ParserT, ScannerT>::type result_t;

    result_t result (p.subject().parse(scan));
    if (!result)
        scan.first = save;
    return result;
}

///////////////////////////////////////////////////////////////////////////////
//  General default case handling (no default_p case branch given).
//  First try to match the current parser node (if the condition value is
//  matched) and, if that fails, return a no_match
template <int N, bool IsDefault, bool HasDefault>
struct default_delegate_parse {

    template <
        typename ParserT, typename DefaultT,
        typename ValueT, typename ScannerT
    >
    static typename parser_result<ParserT, ScannerT>::type
    parse (ValueT const &value, ParserT const &p, DefaultT const &,
        ScannerT const &scan, typename ScannerT::iterator_t const save)
    {
        if (value == N)
            return delegate_parse(p, scan, save);
        return scan.no_match();
    }
};

//  The current case parser node is the default parser.
//  Ignore the given case value and try to match the given default parser.
template <int N, bool HasDefault>
struct default_delegate_parse<N, true, HasDefault> {

    template <
        typename ParserT, typename DefaultT,
        typename ValueT, typename ScannerT
    >
    static typename parser_result<ParserT, ScannerT>::type
    parse (ValueT const& /*value*/, ParserT const &, DefaultT const &d,
        ScannerT const &scan, typename ScannerT::iterator_t const save)
    {
        //  Since there is a default_p case branch defined, the corresponding
        //  parser shouldn't be the nothing_parser
        BOOST_STATIC_ASSERT((!boost::is_same<DefaultT, nothing_parser>::value));
        return delegate_parse(d, scan, save);
    }
};

//  The current case parser node is not the default parser, but there is a
//  default_p branch given inside the switch_p parser.
//  First try to match the current parser node (if the condition value is
//  matched) and, if that fails, match the given default_p parser.
template <int N>
struct default_delegate_parse<N, false, true> {

    template <
        typename ParserT, typename DefaultT,
        typename ValueT, typename ScannerT
    >
    static typename parser_result<ParserT, ScannerT>::type
    parse (ValueT const &value, ParserT const &p, DefaultT const &d,
        ScannerT const &scan, typename ScannerT::iterator_t const save)
    {
        //  Since there is a default_p case branch defined, the corresponding
        //  parser shouldn't be the nothing_parser
        BOOST_STATIC_ASSERT((!boost::is_same<DefaultT, nothing_parser>::value));
        if (value == N)
            return delegate_parse(p, scan, save);

        return delegate_parse(d, scan, save);
    }
};

///////////////////////////////////////////////////////////////////////////////
//  Look through the case parser chain to test, if there is a default case
//  branch defined (returned by 'value').
template <typename CaseT, bool IsSimple = CaseT::is_simple>
struct default_case;

////////////////////////////////////////
template <typename ResultT, bool IsDefault>
struct get_default_parser {

    template <typename ParserT>
    static ResultT
    get(parser<ParserT> const &p)
    {
        return default_case<typename ParserT::derived_t::left_t>::
            get(p.derived().left());
    }
};

template <typename ResultT>
struct get_default_parser<ResultT, true> {

    template <typename ParserT>
    static ResultT
    get(parser<ParserT> const &p) { return p.derived().right(); }
};

////////////////////////////////////////
template <typename CaseT, bool IsSimple>
struct default_case {

    //  The 'value' constant is true, if the current case_parser or one of its
    //  left siblings is a default_p generated case_parser.
    BOOST_STATIC_CONSTANT(bool, value =
        (CaseT::is_default || default_case<typename CaseT::left_t>::value));

    //  The 'is_epsilon' constant is true, if the current case_parser or one of
    //  its left siblings is a default_p generated parser with an attached
    //  epsilon_p (this is generated by the plain default_p).
    BOOST_STATIC_CONSTANT(bool, is_epsilon = (
        (CaseT::is_default && CaseT::is_epsilon) ||
            default_case<typename CaseT::left_t>::is_epsilon
    ));

    //  The computed 'type' represents the type of the default case branch
    //  parser (if there is one) or nothing_parser (if there isn't any default
    //  case branch).
    typedef typename boost::mpl::if_c<
            CaseT::is_default, typename CaseT::right_embed_t,
            typename default_case<typename CaseT::left_t>::type
        >::type type;

    //  The get function returns the parser attached to the default case branch
    //  (if there is one) or an instance of a nothing_parser (if there isn't
    //  any default case branch).
    template <typename ParserT>
    static type
    get(parser<ParserT> const &p)
    { return get_default_parser<type, CaseT::is_default>::get(p); }
};

////////////////////////////////////////
template <typename ResultT, bool IsDefault>
struct get_default_parser_simple {

    template <typename ParserT>
    static ResultT
    get(parser<ParserT> const &p) { return p.derived(); }
};

template <typename ResultT>
struct get_default_parser_simple<ResultT, false> {

    template <typename ParserT>
    static nothing_parser
    get(parser<ParserT> const &) { return nothing_p; }
};

////////////////////////////////////////
//  Specialization of the default_case template for the last (leftmost) element
//  of the case parser chain.
template <typename CaseT>
struct default_case<CaseT, true> {

    //  The 'value' and 'is_epsilon' constant, the 'type' type and the function
    //  'get' are described above.

    BOOST_STATIC_CONSTANT(bool, value = CaseT::is_default);
    BOOST_STATIC_CONSTANT(bool, is_epsilon = (
        CaseT::is_default && CaseT::is_epsilon
    ));

    typedef typename boost::mpl::if_c<
            CaseT::is_default, CaseT, nothing_parser
        >::type type;

    template <typename ParserT>
    static type
    get(parser<ParserT> const &p)
    { return get_default_parser_simple<type, value>::get(p); }
};

///////////////////////////////////////////////////////////////////////////////
//  The case_chain template calculates recursivly the depth of the left
//  subchain of the given case branch node.
template <typename CaseT, bool IsSimple = CaseT::is_simple>
struct case_chain {

    BOOST_STATIC_CONSTANT(int, depth = (
        case_chain<typename CaseT::left_t>::depth + 1
    ));
};

template <typename CaseT>
struct case_chain<CaseT, true> {

    BOOST_STATIC_CONSTANT(int, depth = 0);
};

///////////////////////////////////////////////////////////////////////////////
//  The chain_parser template is used to extract the type and the instance of
//  a left or a right parser, burried arbitrary deep inside the case parser
//  chain.
template <int Depth, typename CaseT>
struct chain_parser {

    typedef typename CaseT::left_t our_left_t;

    typedef typename chain_parser<Depth-1, our_left_t>::left_t  left_t;
    typedef typename chain_parser<Depth-1, our_left_t>::right_t right_t;

    static left_t
    left(CaseT const &p)
    { return chain_parser<Depth-1, our_left_t>::left(p.left()); }

    static right_t
    right(CaseT const &p)
    { return chain_parser<Depth-1, our_left_t>::right(p.left()); }
};

template <typename CaseT>
struct chain_parser<1, CaseT> {

    typedef typename CaseT::left_t  left_t;
    typedef typename CaseT::right_t right_t;

    static left_t left(CaseT const &p) { return p.left(); }
    static right_t right(CaseT const &p) { return p.right(); }
};

template <typename CaseT>
struct chain_parser<0, CaseT>;      // shouldn't be instantiated

///////////////////////////////////////////////////////////////////////////////
//  Type computing meta function for calculating the type of the return value
//  of the used conditional switch expression
template <typename TargetT, typename ScannerT>
struct condition_result {

    typedef typename TargetT::template result<ScannerT>::type type;
};

///////////////////////////////////////////////////////////////////////////////
template <typename LeftT, typename RightT, bool IsDefault>
struct compound_case_parser
:   public binary<LeftT, RightT,
        parser<compound_case_parser<LeftT, RightT, IsDefault> > >
{
    typedef compound_case_parser<LeftT, RightT, IsDefault>    self_t;
    typedef binary_parser_category                  parser_category_t;
    typedef binary<LeftT, RightT, parser<self_t> >  base_t;

    BOOST_STATIC_CONSTANT(int, value = RightT::value);
    BOOST_STATIC_CONSTANT(bool, is_default = IsDefault);
    BOOST_STATIC_CONSTANT(bool, is_simple = false);
    BOOST_STATIC_CONSTANT(bool, is_epsilon = (
        is_default &&
            boost::is_same<typename RightT::subject_t, epsilon_parser>::value
    ));

    compound_case_parser(parser<LeftT> const &lhs, parser<RightT> const &rhs)
    :   base_t(lhs.derived(), rhs.derived())
    {}

    template <typename ScannerT>
    struct result
    {
        typedef typename match_result<ScannerT, nil_t>::type type;
    };

    template <typename ScannerT, typename CondT>
    typename parser_result<self_t, ScannerT>::type
    parse(ScannerT const& scan, CondT const &cond) const;

    template <int N1, typename ParserT1, bool IsDefault1>
    compound_case_parser<
        self_t, case_parser<N1, ParserT1, IsDefault1>, IsDefault1
    >
    operator, (case_parser<N1, ParserT1, IsDefault1> const &p) const
    {
        //  If the following compile time assertion fires, you've probably used
        //  more than one default_p case inside the switch_p parser construct.
        BOOST_STATIC_ASSERT(!default_case<self_t>::value || !IsDefault1);

        //  If this compile time assertion fires, you've probably want to use
        //  more case_p/default_p case branches, than possible.
        BOOST_STATIC_ASSERT(
            case_chain<self_t>::depth < BOOST_SPIRIT_SWITCH_CASE_LIMIT
        );

        typedef case_parser<N1, ParserT1, IsDefault1> right_t;
        return compound_case_parser<self_t, right_t, IsDefault1>(*this, p);
    }
};

///////////////////////////////////////////////////////////////////////////////
//  The parse_switch::do_ functions dispatch to the correct parser, which is
//  selected through the given conditional switch value.
template <int Value, int Depth, bool IsDefault>
struct parse_switch;

///////////////////////////////////////////////////////////////////////////////
//
//  The following generates a couple of parse_switch template specializations
//  with an increasing number of handled case branches (for 1..N).
//
//      template <int Value, bool IsDefault>
//      struct parse_switch<Value, N, IsDefault> {
//
//          template <typename ParserT, typename ScannerT>
//          static typename parser_result<ParserT, ScannerT>::type
//          do_(ParserT const &p, ScannerT const &scan, long cond_value,
//              typename ScannerT::iterator_t const &save)
//          {
//              typedef ParserT left_t0;
//              typedef typename left_t0::left left_t1;
//              ...
//
//              switch (cond_value) {
//              case left_tN::value:
//                  return delegate_parse(chain_parser<
//                          case_chain<ParserT>::depth, ParserT
//                      >::left(p), scan, save);
//              ...
//              case left_t1::value:
//                  return delegate_parse(chain_parser<
//                          1, left_t1
//                      >::right(p.left()), scan, save);
//
//              case left_t0::value:
//              default:
//                  typedef default_case<ParserT> default_t;
//                  typedef default_delegate_parse<
//                              Value, IsDefault, default_t::value>
//                      default_parse_t;
//
//                  return default_parse_t::parse(cond_value, p.right(),
//                      default_t::get(p), scan, save);
//              }
//          }
//      };
//
///////////////////////////////////////////////////////////////////////////////
#define BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS(z, N, _)                         \
    typedef typename BOOST_PP_CAT(left_t, N)::left_t                        \
        BOOST_PP_CAT(left_t, BOOST_PP_INC(N));                              \
    /**/

#define BOOST_SPIRIT_PARSE_SWITCH_CASES(z, N, _)                            \
    case (long)(BOOST_PP_CAT(left_t, N)::value):                            \
        return delegate_parse(chain_parser<N, left_t1>::right(p.left()),    \
            scan, save);                                                    \
    /**/

#define BOOST_SPIRIT_PARSE_SWITCHES(z, N, _)                                \
    template <int Value, bool IsDefault>                                    \
    struct parse_switch<Value, BOOST_PP_INC(N), IsDefault> {                \
                                                                            \
        template <typename ParserT, typename ScannerT>                      \
        static typename parser_result<ParserT, ScannerT>::type              \
        do_(ParserT const &p, ScannerT const &scan, long cond_value,        \
            typename ScannerT::iterator_t const &save)                      \
        {                                                                   \
            typedef ParserT left_t0;                                        \
            BOOST_PP_REPEAT_FROM_TO_ ## z(0, BOOST_PP_INC(N),               \
                BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS, _)                      \
                                                                            \
            switch (cond_value) {                                           \
            case (long)(BOOST_PP_CAT(left_t, BOOST_PP_INC(N))::value):      \
                return delegate_parse(                                      \
                    chain_parser<                                           \
                        case_chain<ParserT>::depth, ParserT                 \
               >::left(p), scan, save);                                \
                                                                            \
            BOOST_PP_REPEAT_FROM_TO_ ## z(1, BOOST_PP_INC(N),               \
                BOOST_SPIRIT_PARSE_SWITCH_CASES, _)                         \
                                                                            \
            case (long)(left_t0::value):                                    \
            default:                                                        \
                typedef default_case<ParserT> default_t;                    \
                typedef                                                     \
                    default_delegate_parse<Value, IsDefault, default_t::value> \
                    default_parse_t;                                        \
                                                                            \
                return default_parse_t::parse(cond_value, p.right(),        \
                    default_t::get(p), scan, save);                         \
            }                                                               \
        }                                                                   \
    };                                                                      \
    /**/

BOOST_PP_REPEAT(BOOST_PP_DEC(BOOST_SPIRIT_SWITCH_CASE_LIMIT),
    BOOST_SPIRIT_PARSE_SWITCHES, _)

#undef BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS
#undef BOOST_SPIRIT_PARSE_SWITCH_CASES
#undef BOOST_SPIRIT_PARSE_SWITCHES
///////////////////////////////////////////////////////////////////////////////

template <typename LeftT, typename RightT, bool IsDefault>
template <typename ScannerT, typename CondT>
inline typename parser_result<
    compound_case_parser<LeftT, RightT, IsDefault>, ScannerT
>::type
compound_case_parser<LeftT, RightT, IsDefault>::
    parse(ScannerT const& scan, CondT const &cond) const
{
    scan.at_end();    // allow skipper to take effect
    return parse_switch<value, case_chain<self_t>::depth, is_default>::
        do_(*this, scan, cond(scan), scan.first);
}

///////////////////////////////////////////////////////////////////////////////
//  The switch condition is to be evaluated from a parser result value.
template <typename ParserT>
struct cond_functor {

    typedef cond_functor<ParserT> self_t;

    cond_functor(ParserT const &p_)
    :   p(p_)
    {}

    template <typename ScannerT>
    struct result
    {
        typedef typename parser_result<ParserT, ScannerT>::type::attr_t type;
    };

    template <typename ScannerT>
    typename condition_result<self_t, ScannerT>::type
    operator()(ScannerT const &scan) const
    {
        typedef typename parser_result<ParserT, ScannerT>::type result_t;
        typedef typename result_t::attr_t attr_t;

        result_t result(p.parse(scan));
        return !result ? attr_t() : result.value();
    }

    typename ParserT::embed_t p;
};

template <typename ParserT>
struct make_cond_functor {

    typedef as_parser<ParserT> as_parser_t;

    static cond_functor<typename as_parser_t::type>
    do_(ParserT const &cond)
    {
        return cond_functor<typename as_parser_t::type>(
            as_parser_t::convert(cond));
    }
};

///////////////////////////////////////////////////////////////////////////////
//  The switch condition is to be evaluated from a phoenix actor
template <typename ActorT>
struct cond_actor {

    typedef cond_actor<ActorT> self_t;

    cond_actor(ActorT const &actor_)
    :   actor(actor_)
    {}

    template <typename ScannerT>
    struct result
    {
        typedef typename ::phoenix::actor_result<ActorT, ::phoenix::tuple<> >::type
            type;
    };

    template <typename ScannerT>
    typename condition_result<self_t, ScannerT>::type
    operator()(ScannerT const& /*scan*/) const
    {
        return actor();
    }

    ActorT const &actor;
};

template <typename ActorT>
struct make_cond_functor< ::phoenix::actor<ActorT> > {

    static cond_actor< ::phoenix::actor<ActorT> >
    do_(::phoenix::actor<ActorT> const &actor)
    {
        return cond_actor< ::phoenix::actor<ActorT> >(actor);
    }
};

///////////////////////////////////////////////////////////////////////////////
//  The switch condition is to be taken directly from the input stream
struct get_next_token_cond {

    typedef get_next_token_cond self_t;

    template <typename ScannerT>
    struct result
    {
        typedef typename ScannerT::value_t type;
    };

    template <typename ScannerT>
    typename condition_result<self_t, ScannerT>::type
    operator()(ScannerT const &scan) const
    {
        typename ScannerT::value_t val(*scan);
        ++scan.first;
        return val;
    }
};

template <>
struct make_cond_functor<get_next_token_cond> {

    static get_next_token_cond
    do_(get_next_token_cond const &cond)
    {
        return cond;
    }
};

///////////////////////////////////////////////////////////////////////////////
}   // namespace impl

BOOST_SPIRIT_CLASSIC_NAMESPACE_END

}}  // namespace boost::spirit

#endif  // BOOST_SPIRIT_SWITCH_IPP
