///////////////////////////////////////////////////////////////////////////////
// peeker.hpp
//
//  Copyright 2008 Eric Niebler. 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)

#ifndef BOOST_XPRESSIVE_DETAIL_CORE_PEEKER_HPP_EAN_10_04_2005
#define BOOST_XPRESSIVE_DETAIL_CORE_PEEKER_HPP_EAN_10_04_2005

// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif

#include <string>
#include <typeinfo>
#include <boost/assert.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/size_t.hpp>
#include <boost/mpl/equal_to.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/xpressive/detail/detail_fwd.hpp>
#include <boost/xpressive/detail/core/matchers.hpp>
#include <boost/xpressive/detail/utility/hash_peek_bitset.hpp>
#include <boost/xpressive/detail/utility/never_true.hpp>
#include <boost/xpressive/detail/utility/algorithm.hpp>

namespace boost { namespace xpressive { namespace detail
{

///////////////////////////////////////////////////////////////////////////////
// peeker_string
//
template<typename Char>
struct peeker_string
{
    Char const *begin_;
    Char const *end_;
    bool icase_;
};

///////////////////////////////////////////////////////////////////////////////
// char_sink
//
template<typename Traits, bool ICase>
struct char_sink
{
    typedef typename Traits::char_type char_type;

    char_sink(hash_peek_bitset<char_type> &bset, Traits const &tr)
      : bset_(bset)
      , traits_(tr)
    {}

    void operator()(char_type ch) const
    {
        this->bset_.set_char(ch, ICase, this->traits_);
    }

    hash_peek_bitset<char_type> &bset_;
    Traits const &traits_;
private:
    char_sink &operator =(char_sink const &);
};

///////////////////////////////////////////////////////////////////////////////
// xpression_peeker
//
template<typename Char>
struct xpression_peeker
{
    template<typename Traits>
    xpression_peeker(hash_peek_bitset<Char> &bset, Traits const &tr, bool has_backrefs = false)
      : bset_(bset)
      , str_()
      , line_start_(false)
      , traits_(0)
      , traits_type_(0)
      , leading_simple_repeat_(0)
      , has_backrefs_(has_backrefs)
    {
        this->set_traits(tr);
    }

    ///////////////////////////////////////////////////////////////////////////////
    // accessors
    peeker_string<Char> const &get_string() const
    {
        return this->str_;
    }

    bool line_start() const
    {
        return this->line_start_;
    }

    bool leading_simple_repeat() const
    {
        return 0 < this->leading_simple_repeat_;
    }

    hash_peek_bitset<Char> const &bitset() const
    {
        return this->bset_;
    }

    ///////////////////////////////////////////////////////////////////////////////
    // modifiers
    void fail()
    {
        this->bset_.set_all();
    }

    template<typename Matcher>
    mpl::false_ accept(Matcher const &)
    {
        this->fail();
        return mpl::false_();
    }

    mpl::true_ accept(mark_begin_matcher const &)
    {
        if(this->has_backrefs_)
        {
            --this->leading_simple_repeat_;
        }
        return mpl::true_();
    }

    mpl::true_ accept(repeat_begin_matcher const &)
    {
        --this->leading_simple_repeat_;
        return mpl::true_();
    }

    template<typename Traits>
    mpl::true_ accept(assert_bol_matcher<Traits> const &)
    {
        this->line_start_ = true;
        return mpl::true_();
    }

    template<typename Traits, typename ICase>
    mpl::false_ accept(literal_matcher<Traits, ICase, mpl::false_> const &xpr)
    {
        this->bset_.set_char(xpr.ch_, ICase(), this->get_traits_<Traits>());
        return mpl::false_();
    }

    template<typename Traits, typename ICase>
    mpl::false_ accept(string_matcher<Traits, ICase> const &xpr)
    {
        this->bset_.set_char(xpr.str_[0], ICase(), this->get_traits_<Traits>());
        this->str_.begin_ = detail::data_begin(xpr.str_);
        this->str_.end_ = detail::data_end(xpr.str_);
        this->str_.icase_ = ICase::value;
        return mpl::false_();
    }

    template<typename Alternates, typename Traits>
    mpl::false_ accept(alternate_matcher<Alternates, Traits> const &xpr)
    {
        BOOST_ASSERT(0 != xpr.bset_.count());
        this->bset_.set_bitset(xpr.bset_);
        return mpl::false_();
    }

    template<typename Matcher, typename Traits, typename ICase>
    mpl::false_ accept(attr_matcher<Matcher, Traits, ICase> const &xpr)
    {
        xpr.sym_.peek(char_sink<Traits, ICase::value>(this->bset_, this->get_traits_<Traits>()));
        return mpl::false_();
    }

    template<typename Xpr, typename Greedy>
    mpl::false_ accept(optional_matcher<Xpr, Greedy> const &)
    {
        this->fail();  // a union of xpr and next
        return mpl::false_();
    }

    template<typename Xpr, typename Greedy>
    mpl::false_ accept(optional_mark_matcher<Xpr, Greedy> const &)
    {
        this->fail();  // a union of xpr and next
        return mpl::false_();
    }

    //template<typename Xpr, typename Greedy>
    //mpl::true_ accept(optional_matcher<Xpr, Greedy> const &xpr)
    //{
    //    xpr.xpr_.peek(*this);  // a union of xpr and next
    //    return mpl::true_();
    //}

    //template<typename Xpr, typename Greedy>
    //mpl::true_ accept(optional_mark_matcher<Xpr, Greedy> const &xpr)
    //{
    //    xpr.xpr_.peek(*this);  // a union of xpr and next
    //    return mpl::true_();
    //}

    template<typename Traits>
    mpl::false_ accept(posix_charset_matcher<Traits> const &xpr)
    {
        this->bset_.set_class(xpr.mask_, xpr.not_, this->get_traits_<Traits>());
        return mpl::false_();
    }

    template<typename ICase, typename Traits>
    typename enable_if<is_narrow_char<typename Traits::char_type>, mpl::false_>::type
    accept(charset_matcher<Traits, ICase, basic_chset<Char> > const &xpr)
    {
        BOOST_ASSERT(0 != xpr.charset_.base().count());
        this->bset_.set_charset(xpr.charset_, ICase());
        return mpl::false_();
    }

    template<typename Traits, typename ICase>
    mpl::false_ accept(range_matcher<Traits, ICase> const &xpr)
    {
        this->bset_.set_range(xpr.ch_min_, xpr.ch_max_, xpr.not_, ICase(), this->get_traits_<Traits>());
        return mpl::false_();
    }

    template<typename Xpr, typename Greedy>
    mpl::false_ accept(simple_repeat_matcher<Xpr, Greedy> const &xpr)
    {
        if(Greedy() && 1U == xpr.width_)
        {
            ++this->leading_simple_repeat_;
            xpr.leading_ = this->leading_simple_repeat();
        }
        0 != xpr.min_ ? xpr.xpr_.peek(*this) : this->fail(); // could be a union of xpr and next
        return mpl::false_();
    }

    template<typename Xpr>
    mpl::false_ accept(keeper_matcher<Xpr> const &xpr)
    {
        xpr.xpr_.peek(*this);
        return mpl::false_();
    }

    template<typename Traits>
    void set_traits(Traits const &tr)
    {
        if(0 == this->traits_)
        {
            this->traits_ = &tr;
            this->traits_type_ = &typeid(Traits);
        }
        else if(*this->traits_type_ != typeid(Traits) || this->get_traits_<Traits>() != tr)
        {
            this->fail(); // traits mis-match! set all and bail
        }
    }

private:
    xpression_peeker(xpression_peeker const &);
    xpression_peeker &operator =(xpression_peeker const &);

    template<typename Traits>
    Traits const &get_traits_() const
    {
        BOOST_ASSERT(!!(*this->traits_type_ == typeid(Traits)));
        return *static_cast<Traits const *>(this->traits_);
    }

    hash_peek_bitset<Char> &bset_;
    peeker_string<Char> str_;
    bool str_icase_;
    bool line_start_;
    void const *traits_;
    std::type_info const *traits_type_;
    int leading_simple_repeat_;
    bool has_backrefs_;
};

}}} // namespace boost::xpressive::detail

#endif
