//  (C) Copyright Gennadiy Rozental 2005-2008.
//  Use, modification, and distribution are 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)

//  See http://www.boost.org/libs/test for the library home page.
//
//  File        : $RCSfile$
//
//  Version     : $Revision: 57992 $
//
//  Description : generic typed_argument_factory implementation
// ***************************************************************************

#ifndef BOOST_RT_CLA_ARGUMENT_FACTORY_HPP_062604GER
#define BOOST_RT_CLA_ARGUMENT_FACTORY_HPP_062604GER

// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>

#include <boost/test/utils/runtime/fwd.hpp>
#include <boost/test/utils/runtime/validation.hpp>
#include <boost/test/utils/runtime/argument.hpp>
#include <boost/test/utils/runtime/trace.hpp>
#include <boost/test/utils/runtime/interpret_argument_value.hpp>

#include <boost/test/utils/runtime/cla/fwd.hpp>
#include <boost/test/utils/runtime/cla/value_generator.hpp>
#include <boost/test/utils/runtime/cla/value_handler.hpp>
#include <boost/test/utils/runtime/cla/validation.hpp>
#include <boost/test/utils/runtime/cla/argv_traverser.hpp>
#include <boost/test/utils/runtime/cla/detail/argument_value_usage.hpp>

#include <boost/test/utils/runtime/cla/iface/argument_factory.hpp>

// Boost.Test
#include <boost/test/utils/callback.hpp>

// Boost
#include <boost/optional.hpp>

namespace boost {

namespace BOOST_RT_PARAM_NAMESPACE {

namespace cla {

// ************************************************************************** //
// **************           default_value_interpreter          ************** //
// ************************************************************************** //

namespace rt_cla_detail {

struct default_value_interpreter {
    template<typename T>
    void operator()( argv_traverser& tr, boost::optional<T>& value )
    {
        if( interpret_argument_value( tr.token(), value, 0 ) )
            tr.next_token();
    }
};

} // namespace rt_cla_detail

// ************************************************************************** //
// **************             typed_argument_factory           ************** //
// ************************************************************************** //

template<typename T>
struct typed_argument_factory : public argument_factory {
    // Constructor
    typed_argument_factory()
    : m_value_interpreter( rt_cla_detail::default_value_interpreter() )
    {}
    BOOST_RT_PARAM_UNNEEDED_VIRTUAL ~typed_argument_factory() {}

    // properties modification
    template<typename Modifier>
    void                accept_modifier( Modifier const& m )
    {
        optionally_assign( m_value_handler, m, handler );
        optionally_assign( m_value_interpreter, m, interpreter );

        if( m.has( default_value ) ) {
            BOOST_RT_PARAM_VALIDATE_LOGIC( !m_value_generator, 
                BOOST_RT_PARAM_LITERAL( "multiple value generators for parameter" ) );

            T const& dv_ref = m[default_value];
            m_value_generator = rt_cla_detail::const_generator<T>( dv_ref );
        }

        if( m.has( default_refer_to ) ) {
            BOOST_RT_PARAM_VALIDATE_LOGIC( !m_value_generator, 
                BOOST_RT_PARAM_LITERAL( "multiple value generators for parameter" ) );

            cstring ref_id = m[default_refer_to];
            m_value_generator = rt_cla_detail::ref_generator<T>( ref_id );
        }

        if( m.has( assign_to ) ) {
            BOOST_RT_PARAM_VALIDATE_LOGIC( !m_value_handler, 
                BOOST_RT_PARAM_LITERAL( "multiple value handlers for parameter" ) );

            m_value_handler = rt_cla_detail::assigner<T>( m[assign_to] );
        }
    }

    // Argument factory implementation
    virtual argument_ptr produce_using( parameter& p, argv_traverser& tr );
    virtual argument_ptr produce_using( parameter& p, parser const& );
    virtual void         argument_usage_info( format_stream& fs );

// !! private?
    // Data members
    unit_test::callback2<parameter const&,T&>                   m_value_handler;
    unit_test::callback2<parser const&,boost::optional<T>&>     m_value_generator;
    unit_test::callback2<argv_traverser&,boost::optional<T>&>   m_value_interpreter;
};

//____________________________________________________________________________//

template<typename T>
inline argument_ptr
typed_argument_factory<T>::produce_using( parameter& p, argv_traverser& tr )
{
    boost::optional<T> value;

    try {
        m_value_interpreter( tr, value );
    }
    catch( ... ) { // !! should we do that?
        BOOST_RT_PARAM_TRACE( "Fail to parse argument value" );

        if( !p.p_optional_value )
            throw;
    }

    argument_ptr actual_arg = p.actual_argument();

    BOOST_RT_CLA_VALIDATE_INPUT( !!value || p.p_optional_value, tr, 
        BOOST_RT_PARAM_LITERAL( "Argument value missing for parameter " ) << p.id_2_report() );

    BOOST_RT_CLA_VALIDATE_INPUT( !actual_arg || p.p_multiplicable, tr, 
        BOOST_RT_PARAM_LITERAL( "Unexpected repetition of the parameter " ) << p.id_2_report() );

    if( !!value && !!m_value_handler )
        m_value_handler( p, *value );

    if( !p.p_multiplicable )
        actual_arg.reset( p.p_optional_value && (rtti::type_id<T>() != rtti::type_id<bool>())
            ? static_cast<argument*>(new typed_argument<boost::optional<T> >( p, value ))
            : static_cast<argument*>(new typed_argument<T>( p, *value )) );
    else {
        typedef std::list<boost::optional<T> > optional_list;

        if( !actual_arg )
            actual_arg.reset( p.p_optional_value 
                ? static_cast<argument*>(new typed_argument<optional_list>( p ))
                : static_cast<argument*>(new typed_argument<std::list<T> >( p )) );

        if( p.p_optional_value ) {
            optional_list& values = arg_value<optional_list>( *actual_arg );

            values.push_back( value );
        }
        else {
            std::list<T>& values = arg_value<std::list<T> >( *actual_arg );
            
            values.push_back( *value );
        }
    }

    return actual_arg;
}

//____________________________________________________________________________//

template<typename T>
inline argument_ptr 
typed_argument_factory<T>::produce_using( parameter& p, parser const& pa )
{
    argument_ptr actual_arg;

    if( !m_value_generator )
        return actual_arg;

    boost::optional<T> value;
    m_value_generator( pa, value );

    if( !value )
        return actual_arg;

    if( !!m_value_handler )
        m_value_handler( p, *value );

    actual_arg.reset( new typed_argument<T>( p, *value ) );

    return actual_arg;
}

//____________________________________________________________________________//

template<typename T>
inline void
typed_argument_factory<T>::argument_usage_info( format_stream& fs )
{
    rt_cla_detail::argument_value_usage( fs, 0, reinterpret_cast<T*>(0) );
}

//____________________________________________________________________________//

} // namespace boost

} // namespace BOOST_RT_PARAM_NAMESPACE

} // namespace cla

#endif // BOOST_RT_CLA_ARGUMENT_FACTORY_HPP_062604GER
