#include "UnitTest++.h"

#include "test_utils.hh"

#include "geners/unordered_mapIO.hh"
#include "geners/unordered_setIO.hh"
#include "geners/StringArchive.hh"
#include "geners/Record.hh"
#include "geners/Reference.hh"

using namespace gs;
using namespace std;

#ifdef CPP11_STD_AVAILABLE

namespace {
    TEST(unorderedIO)
    {
        StringArchive ar0("archive");

        unordered_map<string,int> m0;
        unordered_set<string> s0;
        
        unordered_map<string,int> m1;
        m1.insert(std::make_pair(std::string("haha"),123));
        unordered_set<string> s1;
        s1.insert(std::string("foo"));
        
        unordered_map<string,int> m2;
        for (unsigned i=0; i<10; ++i)
            m2.insert(std::make_pair(random_string(5),
                                     static_cast<int>(test_rng()*10000-5000)));
        unordered_set<string> s2;
        for (unsigned i=0; i<5; ++i)
            s2.insert(random_string(10));

        unordered_multimap<string,int> m3;
        for (unsigned i=0; i<10; ++i)
            m3.insert(std::make_pair(random_string(7),
                                     static_cast<int>(test_rng()*10000-5000)));
        unordered_multiset<string> s3;
        for (unsigned i=0; i<5; ++i)
            s3.insert(random_string(10));

        ar0 << Record(s0, "s0", "top");
        ar0 << Record(s1, "s1", "top");
        ar0 << Record(s2, "s2", "top");
        ar0 << Record(m0, "m0", "top");
        ar0 << Record(m1, "m1", "top");
        ar0 << Record(m2, "m2", "top");
        ar0 << Record(s3, "s3", "top");
        ar0 << Record(m3, "m3", "top");

        // Get them back
        decltype(s0) s0_read;
        Reference<decltype(s0)>(ar0, "s0", "top").restore(0,&s0_read);
        CHECK(s0_read == s0);

        decltype(s1) s1_read;
        Reference<decltype(s1)>(ar0, "s1", "top").restore(0,&s1_read);
        CHECK(s1_read == s1);

        decltype(s2) s2_read;
        Reference<decltype(s2)>(ar0, "s2", "top").restore(0,&s2_read);
        CHECK(s2_read == s2);

        decltype(s3) s3_read;
        Reference<decltype(s3)>(ar0, "s3", "top").restore(0,&s3_read);
        CHECK(s3_read == s3);

        decltype(m0) m0_read;
        Reference<decltype(m0)>(ar0, "m0", "top").restore(0,&m0_read);
        CHECK(m0_read == m0);

        decltype(m1) m1_read;
        Reference<decltype(m1)>(ar0, "m1", "top").restore(0,&m1_read);
        CHECK(m1_read == m1);

        decltype(m2) m2_read;
        Reference<decltype(m2)>(ar0, "m2", "top").restore(0,&m2_read);
        CHECK(m2_read == m2);

        decltype(m3) m3_read;
        Reference<decltype(m3)>(ar0, "m3", "top").restore(0,&m3_read);
        CHECK(m3_read == m3);
    }
}

#else // CPP11_STD_AVAILABLE

namespace {
    TEST(unorderedIO)
    {
    }
}

#endif // CPP11_STD_AVAILABLE
