// (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.

// Allow this file to be used by slice_test.hpp. It is important not to 
// replace BOOST_RESTRICT with BOOST_IOSTREAMS_RESTRICT here, since that
// would interfere with the oepration of the header 
// <boost/iostreams/restrict.hpp>
#include <iostream>

#if defined(BOOST_RESTRICT_USE_SLICE)
#  include <boost/iostreams/slice.hpp>
#  define BOOST_RESTRICT slice
#else
#  include <boost/iostreams/restrict.hpp>
#  define BOOST_RESTRICT restrict
#endif

#include <algorithm>         // equal.
#include <cctype>
#include <iterator>          // back_inserter.
#include <vector>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/device/null.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include "detail/closable.hpp"
#include "detail/constants.hpp"
#include "detail/filters.hpp"
#include "detail/operation_sequence.hpp"
#include "detail/sequence.hpp"
#include "detail/temp_file.hpp"
#include "detail/verification.hpp"

using namespace std;
using namespace boost::iostreams;
using namespace boost::iostreams::test;
using boost::unit_test::test_suite;
namespace io = boost::iostreams;

const char pad_char = '\n';
const int small_padding = 50;
const int large_padding = default_device_buffer_size + 50;

void write_padding(std::ofstream& out, int len)
{
    for (int z = 0; z < len; ++z)
        out.put(pad_char);
}

struct restricted_test_file : public temp_file {
    restricted_test_file(int padding, bool half_open = false)
        {
            BOOST_IOS::openmode mode = 
                BOOST_IOS::out | BOOST_IOS::binary;
            ::std::ofstream f(name().c_str(), mode);
            write_padding(f, padding);
            const char* buf = narrow_data();
            for (int z = 0; z < data_reps; ++z)
                f.write(buf, data_length());
            if (!half_open)
                write_padding(f, padding);
        }
};

struct restricted_test_sequence : public std::vector<char> {
    restricted_test_sequence(int padding, bool half_open = false)
        {
            for (int z = 0; z < padding; ++z)
                push_back(pad_char);
            const char* buf = narrow_data();
            for (int w = 0; w < data_reps; ++w)
                insert(end(), buf, buf + data_length());
            if (!half_open)
                for (int x = 0; x < padding; ++x)
                    push_back(pad_char);
        }
};

struct restricted_uppercase_file : public temp_file {
    restricted_uppercase_file(int padding, bool half_open = false)
        {
            BOOST_IOS::openmode mode = 
                BOOST_IOS::out | BOOST_IOS::binary;
            ::std::ofstream f(name().c_str(), mode);
            write_padding(f, padding);
            const char* buf = narrow_data();
            for (int z = 0; z < data_reps; ++z)
                for (int w = 0; w < data_length(); ++w)
                    f.put((char) std::toupper(buf[w]));
            if (!half_open)
                write_padding(f, padding);
        }
};

struct restricted_lowercase_file : public temp_file {
    restricted_lowercase_file(int padding, bool half_open = false)
        {
            BOOST_IOS::openmode mode = 
                BOOST_IOS::out | BOOST_IOS::binary;
            ::std::ofstream f(name().c_str(), mode);
            write_padding(f, padding);
            const char* buf = narrow_data();
            for (int z = 0; z < data_reps; ++z)
                for (int w = 0; w < data_length(); ++w)
                    f.put((char) std::tolower(buf[w]));
            if (!half_open)
                write_padding(f, padding);
        }
};

// Can't have a restricted view of a non-seekble output filter.
struct tolower_seekable_filter : public seekable_filter {
    typedef char char_type;
    struct category 
        : output_seekable,
          filter_tag
        { };
    template<typename Sink>
    bool put(Sink& s, char c)
    { return boost::iostreams::put(s, (char) std::tolower(c)); }

    template<typename Sink>
    std::streampos seek(Sink& s, stream_offset off, BOOST_IOS::seekdir way)
    { return boost::iostreams::seek(s, off, way); }
};

void read_device()
{
    {
        restricted_test_file   src1(small_padding);
        test_file              src2;
        stream_offset          off = small_padding,
                               len = data_reps * data_length();
        filtering_istream      first( 
            BOOST_RESTRICT(file_source(src1.name(), in_mode), off, len));
        ifstream               second(src2.name().c_str(), in_mode);
        BOOST_CHECK_MESSAGE(
            compare_streams_in_chunks(first, second),
            "failed reading from restriction<Device> with small padding"
        );
    }

    {
        restricted_test_file   src1(large_padding);
        test_file              src2;
        stream_offset          off = large_padding,
                               len = data_reps * data_length();
        filtering_istream      first(
            BOOST_RESTRICT(file_source(src1.name(), in_mode), off, len));
        ifstream               second(src2.name().c_str(), in_mode);
        BOOST_CHECK_MESSAGE(
            compare_streams_in_chunks(first, second),
            "failed reading from restriction<Device> with large padding"
        );
    }

    {
        restricted_test_file   src1(small_padding, true);
        test_file              src2;
        stream_offset          off = small_padding;
        filtering_istream      first(
            BOOST_RESTRICT(file_source(src1.name(), in_mode), off));
        ifstream               second(src2.name().c_str(), in_mode);
        BOOST_CHECK_MESSAGE(
            compare_streams_in_chunks(first, second),
            "failed reading from half-open restriction<Device> "
            "with small padding"
        );
    }

    {
        restricted_test_file   src1(large_padding, true);
        test_file              src2;
        stream_offset          off = large_padding;
        filtering_istream      first(
            BOOST_RESTRICT(file_source(src1.name(), in_mode), off));
        ifstream               second(src2.name().c_str(), in_mode);
        BOOST_CHECK_MESSAGE(
            compare_streams_in_chunks(first, second),
            "failed reading from half-open restriction<Device> "
            "with large padding"
        );
    }
}

void read_direct_device()
{
    {
        test_sequence<char>       first;
        restricted_test_sequence  src(small_padding);
        array_source              array_src(&src[0], &src[0] + src.size());
        stream_offset             off = small_padding,
                                  len = data_reps * data_length();
        filtering_istream         second(BOOST_RESTRICT(array_src, off, len));
        BOOST_CHECK_MESSAGE(
            compare_container_and_stream(first, second),
            "failed reading from restriction<Direct>"
        );
    }

    {
        test_sequence<char>       first;
        restricted_test_sequence  src(small_padding, true);
        array_source              array_src(&src[0], &src[0] + src.size());
        stream_offset             off = small_padding;
        filtering_istream         second(BOOST_RESTRICT(array_src, off));
        BOOST_CHECK_MESSAGE(
            compare_container_and_stream(first, second),
            "failed reading from half-open restriction<Direct>"
        );
    }
}

void read_filter()
{
    {
        restricted_test_file   src1(small_padding);
        uppercase_file         src2;
        stream_offset          off = small_padding,
                               len = data_reps * data_length();
        filtering_istream      first;
        first.push(BOOST_RESTRICT(toupper_filter(), off, len));
        first.push(file_source(src1.name(), in_mode));
        ifstream           second(src2.name().c_str(), in_mode);
        BOOST_CHECK_MESSAGE(
            compare_streams_in_chunks(first, second),
            "failed reading from restriction<Filter> with small padding"
        );
    }

    {
        restricted_test_file   src1(large_padding);
        uppercase_file         src2;
        stream_offset          off = large_padding,
                               len = data_reps * data_length();
        filtering_istream      first;
        first.push(BOOST_RESTRICT(toupper_filter(), off, len));
        first.push(file_source(src1.name(), in_mode));
        ifstream           second(src2.name().c_str(), in_mode);
        BOOST_CHECK_MESSAGE(
            compare_streams_in_chunks(first, second),
            "failed reading from restriction<Filter> with large padding"
        );
    }

    {
        restricted_test_file   src1(small_padding, true);
        uppercase_file         src2;
        stream_offset          off = small_padding;
        filtering_istream      first;
        first.push(BOOST_RESTRICT(toupper_filter(), off));
        first.push(file_source(src1.name(), in_mode));
        ifstream           second(src2.name().c_str(), in_mode);
        BOOST_CHECK_MESSAGE(
            compare_streams_in_chunks(first, second),
            "failed reading from half-open restriction<Filter> "
            "with small padding"
        );
    }

    {
        restricted_test_file   src1(large_padding, true);
        uppercase_file         src2;
        stream_offset          off = large_padding;
        filtering_istream      first;
        first.push(BOOST_RESTRICT(toupper_filter(), off));
        first.push(file_source(src1.name(), in_mode));
        ifstream           second(src2.name().c_str(), in_mode);
        BOOST_CHECK_MESSAGE(
            compare_streams_in_chunks(first, second),
            "failed reading from half-open restriction<Filter> "
            "with large padding"
        );
    }
}

void write_device() 
{
    {
        restricted_uppercase_file  dest1(small_padding);
        restricted_test_file       dest2(small_padding);
        stream_offset              off = small_padding,
                                   len = data_reps * data_length();
        filtering_ostream          out(
            BOOST_RESTRICT(file(dest1.name(), BOOST_IOS::binary), off, len));
        write_data_in_chunks(out);
        out.reset();
        ifstream                   first(dest1.name().c_str(), in_mode);
        ifstream                   second(dest2.name().c_str(), in_mode);
        BOOST_CHECK_MESSAGE(
            compare_streams_in_chunks(first, second),
            "failed writing to restriction<Device> with small padding"
        );
    }

    {
        restricted_uppercase_file  dest1(large_padding);
        restricted_test_file       dest2(large_padding);
        stream_offset              off = large_padding,
                                   len = data_reps * data_length();
        filtering_ostream          out
            (BOOST_RESTRICT(file(dest1.name(), BOOST_IOS::binary), off, len));
        write_data_in_chunks(out);
        out.reset();
        ifstream                   first(dest1.name().c_str(), in_mode);
        ifstream                   second(dest2.name().c_str(), in_mode);
        BOOST_CHECK_MESSAGE(
            compare_streams_in_chunks(first, second),
            "failed writing to restriction<Device> with large padding"
        );
    }

    {
        restricted_uppercase_file  dest1(small_padding, true);
        restricted_test_file       dest2(small_padding, true);
        stream_offset              off = small_padding;
        filtering_ostream          out
            (BOOST_RESTRICT(file(dest1.name(), BOOST_IOS::binary), off));
        write_data_in_chunks(out);
        out.reset();
        ifstream                   first(dest1.name().c_str(), in_mode);
        ifstream                   second(dest2.name().c_str(), in_mode);
        BOOST_CHECK_MESSAGE(
            compare_streams_in_chunks(first, second),
            "failed writing to half-open restriction<Device> "
            "with small padding"
        );
    }

    {
        restricted_uppercase_file  dest1(large_padding, true);
        restricted_test_file       dest2(large_padding, true);
        stream_offset              off = large_padding;
        filtering_ostream          out
            (BOOST_RESTRICT(file(dest1.name(), BOOST_IOS::binary), off));
        write_data_in_chunks(out);
        out.reset();
        ifstream                   first(dest1.name().c_str(), in_mode);
        ifstream                   second(dest2.name().c_str(), in_mode);
        BOOST_CHECK_MESSAGE(
            compare_streams_in_chunks(first, second),
            "failed writing to half-open restriction<Device> "
            "with large padding"
        );
    }
}

void write_direct_device() 
{
    {
        vector<char>              dest1( data_reps * data_length() + 
                                         2 * small_padding, 
                                         '\n' );
        restricted_test_sequence  dest2(small_padding);
        stream_offset             off = small_padding,
                                  len = data_reps * data_length();
        array_sink                array(&dest1[0], &dest1[0] + dest1.size());
        filtering_ostream         out(BOOST_RESTRICT(array, off, len));
        write_data_in_chunks(out);
        out.reset();
        BOOST_CHECK_MESSAGE(
            std::equal(dest1.begin(), dest1.end(), dest2.begin()),
            "failed writing to restriction<Direct>"
        );
    }

    {
        vector<char>              dest1(
            data_reps * data_length() + small_padding, '\n');
        restricted_test_sequence  dest2(small_padding, true);
        stream_offset             off = small_padding;
        array_sink                array(&dest1[0], &dest1[0] + dest1.size());
        filtering_ostream         out(BOOST_RESTRICT(array, off));
        write_data_in_chunks(out);
        out.reset();
        BOOST_CHECK_MESSAGE(
            std::equal(dest1.begin(), dest1.end(), dest2.begin()),
            "failed writing to half-open restriction<Direct>"
        );
    }
}

void write_filter() 
{
    {
        restricted_test_file       dest1(small_padding);
        restricted_lowercase_file  dest2(small_padding);
        stream_offset              off = small_padding,
                                   len = data_reps * data_length();
        filtering_ostream          out;
        out.push(BOOST_RESTRICT(tolower_seekable_filter(), off, len));
        out.push(file(dest1.name(), BOOST_IOS::binary));
        write_data_in_chunks(out);
        out.reset();
        ifstream               first(dest1.name().c_str(), in_mode);
        ifstream               second(dest2.name().c_str(), in_mode);
        BOOST_CHECK_MESSAGE(
            compare_streams_in_chunks(first, second),
            "failed writing to restriction<Filter> with small padding"
        );
    }

    {
        restricted_test_file       dest1(large_padding);
        restricted_lowercase_file  dest2(large_padding);
        stream_offset              off = large_padding,
                                   len = data_reps * data_length();
        filtering_ostream          out;
        out.push(BOOST_RESTRICT(tolower_seekable_filter(), off, len));
        out.push(file(dest1.name(), BOOST_IOS::binary));
        write_data_in_chunks(out);
        out.reset();
        ifstream               first(dest1.name().c_str(), in_mode);
        ifstream               second(dest2.name().c_str(), in_mode);
        BOOST_CHECK_MESSAGE(
            compare_streams_in_chunks(first, second),
            "failed writing to restriction<Filter> with large padding"
        );
    }

    {
        restricted_test_file       dest1(small_padding, true);
        restricted_lowercase_file  dest2(small_padding, true);
        stream_offset              off = small_padding;
        filtering_ostream          out;
        out.push(BOOST_RESTRICT(tolower_seekable_filter(), off));
        out.push(file(dest1.name(), BOOST_IOS::binary));
        write_data_in_chunks(out);
        out.reset();
        ifstream               first(dest1.name().c_str(), in_mode);
        ifstream               second(dest2.name().c_str(), in_mode);
        BOOST_CHECK_MESSAGE(
            compare_streams_in_chunks(first, second),
            "failed writing to restriction<Filter> with small padding"
        );
    }

    {
        restricted_test_file       dest1(large_padding, true);
        restricted_lowercase_file  dest2(large_padding, true);
        stream_offset              off = large_padding;
        filtering_ostream          out;
        out.push(BOOST_RESTRICT(tolower_seekable_filter(), off));
        out.push(file(dest1.name(), BOOST_IOS::binary));
        write_data_in_chunks(out);
        out.reset();
        ifstream                   first(dest1.name().c_str(), in_mode);
        ifstream                   second(dest2.name().c_str(), in_mode);
        BOOST_CHECK_MESSAGE(
            compare_streams_in_chunks(first, second),
            "failed writing to restriction<Filter> with large padding"
        );
    }
}

void seek_device()
{
    {
        restricted_test_file       src(large_padding);
        stream_offset              off = large_padding,
                                   len = data_reps * data_length();
        filtering_stream<seekable> io(
            BOOST_RESTRICT(file(src.name(), BOOST_IOS::binary), off, len));
        BOOST_CHECK_MESSAGE(
            test_seekable_in_chunks(io),
            "failed seeking within restriction<Device>"
        );
    }

    {
        restricted_test_file       src(large_padding, true);
        stream_offset              off = large_padding;
        filtering_stream<seekable> io(
            BOOST_RESTRICT(file(src.name(), BOOST_IOS::binary), off));
        BOOST_CHECK_MESSAGE(
            test_seekable_in_chunks(io),
            "failed seeking within half-open restriction<Device>"
        );
    }
}

void seek_direct_device()
{
    {
        vector<char>               src(
            data_reps * data_length() + 2 * small_padding, '\n');
        stream_offset              off = small_padding,
                                   len = data_reps * data_length();
        array                      ar(&src[0], &src[0] + src.size());
        filtering_stream<seekable> io(BOOST_RESTRICT(ar, off, len));
        BOOST_CHECK_MESSAGE(
            test_seekable_in_chars(io),
            "failed seeking within restriction<Direct> with small padding"
        );
    }

    {
        vector<char>               src(
            data_reps * data_length() + small_padding, '\n');
        stream_offset              off = small_padding;
        array                      ar(&src[0], &src[0] + src.size());
        filtering_stream<seekable> io(BOOST_RESTRICT(ar, off));
        BOOST_CHECK_MESSAGE(
            test_seekable_in_chars(io),
            "failed seeking within half-open restriction<Direct> "
            "with small padding"
        );
    }
}

void seek_filter()
{
    {
        restricted_test_file       src(small_padding);
        stream_offset              off = large_padding,
                                   len = data_reps * data_length();
        filtering_stream<seekable> io;
        io.push(BOOST_RESTRICT(identity_seekable_filter(), off, len));
        io.push(file(src.name(), BOOST_IOS::binary));
        BOOST_CHECK_MESSAGE(
            test_seekable_in_chars(io),
            "failed seeking within restriction<Device>"
        );
    }

    {
        restricted_test_file       src(small_padding, true);
        stream_offset              off = large_padding;
        filtering_stream<seekable> io;
        io.push(BOOST_RESTRICT(identity_seekable_filter(), off));
        io.push(file(src.name(), BOOST_IOS::binary));
        BOOST_CHECK_MESSAGE(
            test_seekable_in_chars(io),
            "failed seeking within half-open restriction<Device>"
        );
    }
}

void close_device()
{
    // Restrict a source
    {
        operation_sequence  seq;
        chain<input>        ch;
        ch.push(
            io::BOOST_RESTRICT(
                closable_device<input>(seq.new_operation(1)), 
                0
            )
        );
        BOOST_CHECK_NO_THROW(ch.reset());
        BOOST_CHECK_OPERATION_SEQUENCE(seq);
    }

    // Restrict a seekable device
    {
        operation_sequence  seq;
        chain<seekable>     ch;
        ch.push(
            io::BOOST_RESTRICT(
                closable_device<seekable>(seq.new_operation(1)), 
                0
            )
        );
        BOOST_CHECK_NO_THROW(ch.reset());
        BOOST_CHECK_OPERATION_SEQUENCE(seq);
    }

    // Restrict a direct source
    {
        operation_sequence  seq;
        chain<input>        ch;
        ch.push(
            io::BOOST_RESTRICT(
                closable_device<direct_input>(seq.new_operation(1)), 
                0
            )
        );
        BOOST_CHECK_NO_THROW(ch.reset());
        BOOST_CHECK_OPERATION_SEQUENCE(seq);
    }

    // Restrict a direct seekable device
    {
        operation_sequence  seq;
        chain<seekable>     ch;
        ch.push(
            io::BOOST_RESTRICT(
                closable_device<direct_seekable>(seq.new_operation(1)), 
                0
            )
        );
        BOOST_CHECK_NO_THROW(ch.reset());
        BOOST_CHECK_OPERATION_SEQUENCE(seq);
    }
}

void close_filter()
{
    // Restrict an input filter
    {
        operation_sequence  seq;
        chain<input>        ch;
        ch.push(
            io::BOOST_RESTRICT(
                closable_filter<input>(seq.new_operation(2)), 
                0
            )
        );
        ch.push(closable_device<input>(seq.new_operation(1)));
        BOOST_CHECK_NO_THROW(ch.reset());
        BOOST_CHECK_OPERATION_SEQUENCE(seq);
    }

    // Restrict a seekable filter
    {
        operation_sequence  seq;
        chain<seekable>     ch;
        ch.push(
            io::BOOST_RESTRICT(
                closable_filter<seekable>(seq.new_operation(1)), 
                0
            )
        );
        ch.push(closable_device<seekable>(seq.new_operation(2)));
        BOOST_CHECK_NO_THROW(ch.reset());
        BOOST_CHECK_OPERATION_SEQUENCE(seq);
    }

    // Restrict a dual_use filter for input
    {
        operation_sequence  seq;
        chain<input>        ch;
        operation           dummy;
        ch.push(
            io::BOOST_RESTRICT(
                closable_filter<dual_use>(
                    seq.new_operation(2),
                    dummy
                ),
                0
            )
        );
        ch.push(closable_device<input>(seq.new_operation(1)));
        BOOST_CHECK_NO_THROW(ch.reset());
        BOOST_CHECK_OPERATION_SEQUENCE(seq);
    }

    // Restrict a dual_use filter for output
    {
        operation_sequence  seq;
        chain<output>       ch;
        operation           dummy;
        ch.push(
            io::BOOST_RESTRICT(
                closable_filter<dual_use>(
                    dummy,
                    seq.new_operation(1)
                ),
                0
            )
        );
        ch.push(closable_device<output>(seq.new_operation(2)));
        BOOST_CHECK_NO_THROW(ch.reset());
        BOOST_CHECK_OPERATION_SEQUENCE(seq);
    }
}

test_suite* init_unit_test_suite(int, char* []) 
{
    test_suite* test = 
        BOOST_TEST_SUITE(BOOST_STRINGIZE(BOOST_RESTRICT) " test");
    test->add(BOOST_TEST_CASE(&read_device));
    test->add(BOOST_TEST_CASE(&read_direct_device));
    test->add(BOOST_TEST_CASE(&read_filter));
    test->add(BOOST_TEST_CASE(&write_device));
    test->add(BOOST_TEST_CASE(&write_direct_device));
    test->add(BOOST_TEST_CASE(&write_filter));
    test->add(BOOST_TEST_CASE(&seek_device));
    test->add(BOOST_TEST_CASE(&seek_direct_device));
    test->add(BOOST_TEST_CASE(&close_device));
    test->add(BOOST_TEST_CASE(&close_filter));
    return test;
}
