#include <sstream>
#include "UnitTest++.h"

#include "test_utils.hh"

#include "geners/CompressedIO.hh"
#include "geners/StringArchive.hh"
#include "geners/Record.hh"
#include "geners/Reference.hh"

using namespace gs;
using namespace std;

namespace {
    TEST(compressedIO_read)
    {
        StringArchive ar;

        const unsigned len = 100000;
        std::string s(len, '\0');
        for (unsigned i=0; i<len; ++i)
            s[i] = i % 128;
        ar << Record(s, "dummy", "haha");

        std::ostringstream os;
        CHECK(write_compressed_item(os, ar));

        std::istringstream is(os.str());
        CPP11_auto_ptr<StringArchive> par = 
           read_compressed_item<StringArchive>(is);
        CHECK(ar == *par);

        Reference<std::string> ref(*par, "dummy", "haha");
        CHECK(ref.unique());
        std::string rb;
        ref.restore(0, &rb);
        CHECK(rb == s);
    }

    TEST(compressedIO_restore)
    {
        std::ostringstream os1;
        std::ostringstream os2;

        const unsigned len = 100000;
        std::string s(len, '\0');
        for (unsigned i=0; i<len; ++i)
            s[i] = i % 128;

        CHECK(write_item(os1, s));
        CHECK(write_compressed_item(os2, s));

        // Size of compressed string should be smaller
        const std::string& st1 = os1.str();
        const std::string& st2 = os2.str();
        CHECK(st2.size() < st1.size());

        std::istringstream is1(st1);
        std::string rb1;
        restore_item(is1, &rb1);
        CHECK(rb1 == s);

        std::istringstream is2(st2);
        std::string rb2;
        restore_compressed_item(is2, &rb2);
        CHECK(rb2 == s);
    }
}
