// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
// (C) Copyright 2005-2007 Jonathan Turkanis
// 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.)

// See http://www.boost.org/libs/iostreams for documentation.

#ifndef NDNBOOST_IOSTREAMS_TEE_HPP_INCLUDED
#define NDNBOOST_IOSTREAMS_TEE_HPP_INCLUDED

#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif

#include <ndnboost/assert.hpp>
#include <ndnboost/config.hpp>  // NDNBOOST_DEDUCE_TYPENAME.
#include <ndnboost/iostreams/categories.hpp>
#include <ndnboost/iostreams/detail/adapter/device_adapter.hpp>
#include <ndnboost/iostreams/detail/adapter/filter_adapter.hpp>
#include <ndnboost/iostreams/detail/call_traits.hpp>
#include <ndnboost/iostreams/detail/execute.hpp>
#include <ndnboost/iostreams/detail/functional.hpp>  // call_close_all 
#include <ndnboost/iostreams/operations.hpp>
#include <ndnboost/iostreams/pipeline.hpp>
#include <ndnboost/iostreams/traits.hpp>
#include <ndnboost/static_assert.hpp>
#include <ndnboost/type_traits/is_convertible.hpp>
#include <ndnboost/type_traits/is_same.hpp>

namespace ndnboost { namespace iostreams {

//
// Template name: tee_filter.
// Template parameters:
//      Device - A blocking Sink.
//
template<typename Device>
class tee_filter : public detail::filter_adapter<Device> {
public:
    typedef typename detail::param_type<Device>::type  param_type;
    typedef typename char_type_of<Device>::type        char_type;
    struct category
        : dual_use_filter_tag,
          multichar_tag,
          closable_tag,
          flushable_tag,
          localizable_tag,
          optimally_buffered_tag
        { };

    NDNBOOST_STATIC_ASSERT(is_device<Device>::value);
    NDNBOOST_STATIC_ASSERT((
        is_convertible< // Using mode_of causes failures on VC6-7.0.
            NDNBOOST_DEDUCED_TYPENAME iostreams::category_of<Device>::type, output
        >::value
    ));

    explicit tee_filter(param_type dev) 
        : detail::filter_adapter<Device>(dev) 
        { }

    template<typename Source>
    std::streamsize read(Source& src, char_type* s, std::streamsize n)
    {
        std::streamsize result = iostreams::read(src, s, n);
        if (result != -1) {
            std::streamsize result2 = iostreams::write(this->component(), s, result);
            (void) result2; // Suppress 'unused variable' warning.
            NDNBOOST_ASSERT(result == result2);
        }
        return result;
    }

    template<typename Sink>
    std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
    {
        std::streamsize result = iostreams::write(snk, s, n);
        std::streamsize result2 = iostreams::write(this->component(), s, result);
        (void) result2; // Suppress 'unused variable' warning.
        NDNBOOST_ASSERT(result == result2);
        return result;
    }

    template<typename Next>
    void close(Next&, NDNBOOST_IOS::openmode)
    { 
        detail::close_all(this->component());
    }

    template<typename Sink>
    bool flush(Sink& snk)
    {
        bool r1 = iostreams::flush(snk);
        bool r2 = iostreams::flush(this->component());
        return r1 && r2;
    }
};
NDNBOOST_IOSTREAMS_PIPABLE(tee_filter, 1)

//
// Template name: tee_device.
// Template parameters:
//      Device - A blocking Device.
//      Sink - A blocking Sink.
//
template<typename Device, typename Sink>
class tee_device {
public:
    typedef typename detail::param_type<Device>::type  device_param;
    typedef typename detail::param_type<Sink>::type    sink_param;
    typedef typename detail::value_type<Device>::type  device_value;
    typedef typename detail::value_type<Sink>::type    sink_value;
    typedef typename char_type_of<Device>::type        char_type;
    typedef typename
            mpl::if_<
                 is_convertible<
                     NDNBOOST_DEDUCED_TYPENAME 
                         iostreams::category_of<Device>::type, 
                     output
                 >,
                 output,
                 input
            >::type                                    mode;
    NDNBOOST_STATIC_ASSERT(is_device<Device>::value);
    NDNBOOST_STATIC_ASSERT(is_device<Sink>::value);
    NDNBOOST_STATIC_ASSERT((
        is_same<
            char_type, 
            NDNBOOST_DEDUCED_TYPENAME char_type_of<Sink>::type
        >::value
    ));
    NDNBOOST_STATIC_ASSERT((
        is_convertible<
            NDNBOOST_DEDUCED_TYPENAME iostreams::category_of<Sink>::type, 
            output
        >::value
    ));
    struct category
        : mode,
          device_tag,
          closable_tag,
          flushable_tag,
          localizable_tag,
          optimally_buffered_tag
        { };
    tee_device(device_param device, sink_param sink) 
        : dev_(device), sink_(sink)
        { }
    std::streamsize read(char_type* s, std::streamsize n)
    {
        NDNBOOST_STATIC_ASSERT((
            is_convertible<
                NDNBOOST_DEDUCED_TYPENAME iostreams::category_of<Device>::type, input
            >::value
        ));
        std::streamsize result1 = iostreams::read(dev_, s, n);
        if (result1 != -1) {
            std::streamsize result2 = iostreams::write(sink_, s, result1);
            (void) result1; // Suppress 'unused variable' warning.
            (void) result2;
            NDNBOOST_ASSERT(result1 == result2);
        }
        return result1;
    }
    std::streamsize write(const char_type* s, std::streamsize n)
    {
        NDNBOOST_STATIC_ASSERT((
            is_convertible<
                NDNBOOST_DEDUCED_TYPENAME iostreams::category_of<Device>::type, output
            >::value
        ));
        std::streamsize result1 = iostreams::write(dev_, s, n);
        std::streamsize result2 = iostreams::write(sink_, s, n);
        (void) result1; // Suppress 'unused variable' warning.
        (void) result2;
        NDNBOOST_ASSERT(result1 == n && result2 == n);
        return n;
    }
    void close()
    {
        detail::execute_all( detail::call_close_all(dev_),
                             detail::call_close_all(sink_) );
    }
    bool flush()
    {
        bool r1 = iostreams::flush(dev_);
        bool r2 = iostreams::flush(sink_);
        return r1 && r2;
    }
    template<typename Locale>
    void imbue(const Locale& loc)
    {
        iostreams::imbue(dev_, loc);
        iostreams::imbue(sink_, loc);
    }
    std::streamsize optimal_buffer_size() const 
    {
        return (std::max) ( iostreams::optimal_buffer_size(dev_), 
                            iostreams::optimal_buffer_size(sink_) );
    }
private:
    device_value  dev_;
    sink_value    sink_;
};

template<typename Sink>
tee_filter<Sink> tee(Sink& snk) 
{ return tee_filter<Sink>(snk); }

template<typename Sink>
tee_filter<Sink> tee(const Sink& snk) 
{ return tee_filter<Sink>(snk); }

template<typename Device, typename Sink>
tee_device<Device, Sink> tee(Device& dev, Sink& sink) 
{ return tee_device<Device, Sink>(dev, sink); }

template<typename Device, typename Sink>
tee_device<Device, Sink> tee(const Device& dev, Sink& sink) 
{ return tee_device<Device, Sink>(dev, sink); }

template<typename Device, typename Sink>
tee_device<Device, Sink> tee(Device& dev, const Sink& sink) 
{ return tee_device<Device, Sink>(dev, sink); }

template<typename Device, typename Sink>
tee_device<Device, Sink> tee(const Device& dev, const Sink& sink) 
{ return tee_device<Device, Sink>(dev, sink); }

} } // End namespaces iostreams, boost.

#endif // #ifndef NDNBOOST_IOSTREAMS_TEE_HPP_INCLUDED
