/*=============================================================================
    Copyright (c) 2001-2010 Joel de Guzman

    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)
==============================================================================*/
#if !defined(BOOST_SPIRIT_ERROR_HANDLER_APRIL_29_2007_1042PM)
#define BOOST_SPIRIT_ERROR_HANDLER_APRIL_29_2007_1042PM

#if defined(_MSC_VER)
#pragma once
#endif

#include <boost/spirit/home/qi/operator/expect.hpp>
#include <boost/spirit/home/qi/nonterminal/rule.hpp>
#include <boost/spirit/home/support/multi_pass_wrapper.hpp>
#include <boost/function.hpp>
#include <boost/assert.hpp>

namespace boost { namespace spirit { namespace qi
{
    enum error_handler_result
    {
        fail
      , retry
      , accept
      , rethrow
    };

    namespace detail
    {
        // Helper template allowing to manage the inhibit clear queue flag in
        // a multi_pass iterator. This is the usual specialization used for
        // anything but a multi_pass iterator.
        template <typename Iterator, bool active>
        struct reset_on_exit
        {
            reset_on_exit(Iterator&) {}
        };

        // For 'retry' or 'fail' error handlers we need to inhibit the flushing 
        // of the internal multi_pass buffers which otherwise might happen at 
        // deterministic expectation points inside the encapsulated right hand 
        // side of rule.
        template <typename Iterator>
        struct reset_on_exit<Iterator, true>
        {
            reset_on_exit(Iterator& it)
              : it_(it)
              , inhibit_clear_queue_(spirit::traits::inhibit_clear_queue(it)) 
            {
                spirit::traits::inhibit_clear_queue(it_, true);
            }

            ~reset_on_exit()
            {
                // reset inhibit flag in multi_pass on exit
                spirit::traits::inhibit_clear_queue(it_, inhibit_clear_queue_);
            }

            Iterator& it_;
            bool inhibit_clear_queue_;
        };
    }

    template <
        typename Iterator, typename Context
      , typename Skipper, typename F, error_handler_result action
    >
    struct error_handler
    {
        typedef function<
            bool(Iterator& first, Iterator const& last
              , Context& context
              , Skipper const& skipper
            )>
        function_type;

        error_handler(function_type subject, F f)
          : subject(subject)
          , f(f)
        {
        }

        bool operator()(
            Iterator& first, Iterator const& last
          , Context& context, Skipper const& skipper) const
        {
            typedef qi::detail::reset_on_exit<Iterator
              , traits::is_multi_pass<Iterator>::value && 
                  (action == retry || action == fail)> on_exit_type;

            on_exit_type on_exit(first);
            for(;;)
            {
                try
                {
                    Iterator i = first;
                    bool r = subject(i, last, context, skipper);
                    if (r)
                        first = i;
                    return r;
                }
                catch (expectation_failure<Iterator> const& x)
                {
                    typedef
                        fusion::vector<
                            Iterator&
                          , Iterator const&
                          , Iterator const&
                          , info const&>
                    params;
                    error_handler_result r = action;
                    params args(first, last, x.first, x.what_);
                    f(args, context, r);

                    // The assertions below will fire if you are using a
                    // multi_pass as the underlying iterator, one of your error
                    // handlers forced its guarded rule to 'fail' or 'retry',
                    // and the error handler has not been instantiated using
                    // either 'fail' or 'retry' in the first place. Please see 
                    // the multi_pass docs for more information.
                    switch (r)
                    {
                        case fail: 
                            BOOST_ASSERT(
                                !traits::is_multi_pass<Iterator>::value ||
                                (action != retry && action != fail));
                            return false;
                        case retry: 
                            BOOST_ASSERT(
                                !traits::is_multi_pass<Iterator>::value ||
                                (action != retry && action != fail));
                            continue;
                        case accept: return true;
                        case rethrow: boost::throw_exception(x);
                    }
                }
            }
            return false;
        }

        function_type subject;
        F f;
    };

    template <
        error_handler_result action
      , typename Iterator, typename T0, typename T1, typename T2
      , typename F>
    void on_error(rule<Iterator, T0, T1, T2>& r, F f)
    {
        typedef rule<Iterator, T0, T1, T2> rule_type;

        typedef
            error_handler<
                Iterator
              , typename rule_type::context_type
              , typename rule_type::skipper_type
              , F
              , action>
        error_handler;
        r.f = error_handler(r.f, f);
    }

    // Error handling support when <action> is not
    // specified. We will default to <fail>.
    template <typename Iterator, typename T0, typename T1
      , typename T2, typename F>
    void on_error(rule<Iterator, T0, T1, T2>& r, F f)
    {
        on_error<fail>(r, f);
    }
}}}

#endif
