#include <msgpack.hpp>
#include <gtest/gtest.h>
#include <sstream>

TEST(streaming, basic)
{
    msgpack::sbuffer buffer;

    msgpack::packer<msgpack::sbuffer> pk(&buffer);
    pk.pack(1);
    pk.pack(2);
    pk.pack(3);

    const char* input = buffer.data();
    const char* const eof = input + buffer.size();

    msgpack::unpacker pac;
    msgpack::unpacked result;

    int count = 0;
    while(count < 3) {
        pac.reserve_buffer(32*1024);

        // read buffer into pac.buffer() upto
        // pac.buffer_capacity() bytes.
        size_t len = 1;
        memcpy(pac.buffer(), input, len);
        input += len;

        pac.buffer_consumed(len);

        while(pac.next(result)) {
            msgpack::object obj = result.get();
            switch(count++) {
            case 0:
                EXPECT_EQ(1, obj.as<int>());
                break;
            case 1:
                EXPECT_EQ(2, obj.as<int>());
                break;
            case 2:
                EXPECT_EQ(3, obj.as<int>());
                return;
            }
        }

        EXPECT_TRUE(input < eof);
    }
}

TEST(streaming, basic_pointer)
{
    msgpack::sbuffer buffer;

    msgpack::packer<msgpack::sbuffer> pk(&buffer);
    pk.pack(1);
    pk.pack(2);
    pk.pack(3);

    const char* input = buffer.data();
    const char* const eof = input + buffer.size();

    msgpack::unpacker pac;
    msgpack::unpacked result;

    int count = 0;
    while(count < 3) {
        pac.reserve_buffer(32*1024);

        // read buffer into pac.buffer() upto
        // pac.buffer_capacity() bytes.
        size_t len = 1;
        memcpy(pac.buffer(), input, len);
        input += len;

        pac.buffer_consumed(len);

        while(pac.next(&result)) {
            msgpack::object obj = result.get();
            switch(count++) {
            case 0:
                EXPECT_EQ(1, obj.as<int>());
                break;
            case 1:
                EXPECT_EQ(2, obj.as<int>());
                break;
            case 2:
                EXPECT_EQ(3, obj.as<int>());
                return;
            }
        }

        EXPECT_TRUE(input < eof);
    }
}

#if !defined(MSGPACK_USE_CPP03)

TEST(streaming, move)
{
    msgpack::sbuffer buffer;

    msgpack::packer<msgpack::sbuffer> pk(&buffer);
    pk.pack(1);
    pk.pack(2);
    pk.pack(3);

    const char* input = buffer.data();
    const char* const eof = input + buffer.size();

    msgpack::unpacker pac;
    msgpack::unpacked result;

    int count = 0;
    while(count < 3) {
        msgpack::unpacker pac_in(std::move(pac));
        pac_in.reserve_buffer(32*1024);

        // read buffer into pac_in.buffer() upto
        // pac_in.buffer_capac_inity() bytes.
        size_t len = 1;
        memcpy(pac_in.buffer(), input, len);
        input += len;

        pac_in.buffer_consumed(len);

        while(pac_in.next(result)) {
            msgpack::object obj = result.get();
            switch(count++) {
            case 0:
                EXPECT_EQ(1, obj.as<int>());
                break;
            case 1:
                EXPECT_EQ(2, obj.as<int>());
                break;
            case 2:
                EXPECT_EQ(3, obj.as<int>());
                return;
            }
        }

        EXPECT_TRUE(input < eof);
        pac = std::move(pac_in);
    }
}

#endif // !defined(MSGPACK_USE_CPP03)

class event_handler {
public:
    event_handler(std::istream& input) : input(input) { }
    ~event_handler() { }

    void on_read()
    {
        while(true) {
            pac.reserve_buffer(32*1024);

            size_t len = static_cast<size_t>(input.readsome(pac.buffer(), pac.buffer_capacity()));

            if(len == 0) {
                return;
            }

            pac.buffer_consumed(len);

            msgpack::unpacked result;
            while(pac.next(result)) {
                on_message(result.get(), msgpack::move(result.zone()));
            }

            if(pac.message_size() > 10*1024*1024) {
                throw std::runtime_error("message is too large");
            }
        }
    }

    void on_message(msgpack::object obj, msgpack::unique_ptr<msgpack::zone>)
    {
        EXPECT_EQ(expect, obj.as<int>());
    }

    int expect;

private:
    std::istream& input;
    msgpack::unpacker pac;
};

TEST(streaming, event)
{
    std::stringstream stream;
    msgpack::packer<std::ostream> pk(&stream);

    event_handler handler(stream);

    pk.pack(1);
    handler.expect = 1;
    handler.on_read();

    pk.pack(2);
    handler.expect = 2;
    handler.on_read();

    pk.pack(3);
    handler.expect = 3;
    handler.on_read();
}


// backward compatibility
TEST(streaming, basic_compat)
{
    std::ostringstream stream;
    msgpack::packer<std::ostream> pk(&stream);

    pk.pack(1);
    pk.pack(2);
    pk.pack(3);

    std::istringstream input(stream.str());

    msgpack::unpacker pac;

    int count = 0;
    while(count < 3) {
        pac.reserve_buffer(32*1024);

        size_t len = static_cast<size_t>(input.readsome(pac.buffer(), pac.buffer_capacity()));
        pac.buffer_consumed(len);

        while(pac.execute()) {
            msgpack::unique_ptr<msgpack::zone> z(pac.release_zone());
            msgpack::object obj = pac.data();
            pac.reset();

            switch(count++) {
            case 0:
                EXPECT_EQ(1, obj.as<int>());
                break;
            case 1:
                EXPECT_EQ(2, obj.as<int>());
                break;
            case 2:
                EXPECT_EQ(3, obj.as<int>());
                return;
            }

        }
    }
}


// backward compatibility
class event_handler_compat {
public:
    event_handler_compat(std::istream& input) : input(input) { }
    ~event_handler_compat() { }

    void on_read()
    {
        while(true) {
            pac.reserve_buffer(32*1024);

            size_t len = static_cast<size_t>(input.readsome(pac.buffer(), pac.buffer_capacity()));

            if(len == 0) {
                return;
            }

            pac.buffer_consumed(len);

            while(pac.execute()) {
                msgpack::unique_ptr<msgpack::zone> z(pac.release_zone());
                msgpack::object obj = pac.data();
                pac.reset();
                on_message(obj, msgpack::move(z));
            }

            if(pac.message_size() > 10*1024*1024) {
                throw std::runtime_error("message is too large");
            }
        }
    }

    void on_message(msgpack::object obj, msgpack::unique_ptr<msgpack::zone>)
    {
        EXPECT_EQ(expect, obj.as<int>());
    }

    int expect;

private:
    std::istream& input;
    msgpack::unpacker pac;
};

TEST(streaming, event_compat)
{
    std::stringstream stream;
    msgpack::packer<std::ostream> pk(&stream);

    event_handler_compat handler(stream);

    pk.pack(1);
    handler.expect = 1;
    handler.on_read();

    pk.pack(2);
    handler.expect = 2;
    handler.on_read();

    pk.pack(3);
    handler.expect = 3;
    handler.on_read();
}
