#include <gtest/gtest.h>

#include <serializer.h>
#include <operators.hpp>

TEST(Serialization, Double) {
    double source1 = 5344.6542;
    double source2 = 0.4329248;
    LMDBAL::Serializer<double> serializer;
    LMDBAL::Serializer<double> serializer2(source1);
    LMDBAL::Serializer<double> deserializer;

    serializer.setData(source1);
    MDB_val data = serializer.getData();
    MDB_val data2 = serializer2.getData();

    EXPECT_EQ(data.mv_size, data2.mv_size);
    EXPECT_EQ(std::memcmp(data.mv_data, data2.mv_data, data.mv_size), 0);

    double destination;
    serializer.deserialize(data, destination);

    EXPECT_DOUBLE_EQ(source1, destination);

    double dest2 = serializer.deserialize(data);

    EXPECT_DOUBLE_EQ(source1, dest2);

    data = serializer.setData(source2);
    serializer.deserialize(data, destination);

    EXPECT_DOUBLE_EQ(source2, destination);
}

TEST(Serialization, Float) {
    float source = 5.156;
    LMDBAL::Serializer<float> serializer;
    LMDBAL::Serializer<float> serializer2(source);
    LMDBAL::Serializer<float> deserializer;

    serializer.setData(source);
    MDB_val data = serializer.getData();
    MDB_val data2 = serializer2.getData();

    EXPECT_EQ(data.mv_size, data2.mv_size);
    EXPECT_EQ(std::memcmp(data.mv_data, data2.mv_data, data.mv_size), 0);

    float destination;
    serializer.deserialize(data, destination);

    EXPECT_FLOAT_EQ(source, destination);

    float dest2 = serializer.deserialize(data);

    EXPECT_FLOAT_EQ(source, dest2);
}

TEST(Serialization, Int8) {
    int8_t source = 38;
    LMDBAL::Serializer<int8_t> serializer;
    LMDBAL::Serializer<int8_t> serializer2(source);
    LMDBAL::Serializer<int8_t> deserializer;

    serializer.setData(source);
    MDB_val data = serializer.getData();
    MDB_val data2 = serializer2.getData();

    EXPECT_EQ(data.mv_size, data2.mv_size);
    EXPECT_EQ(std::memcmp(data.mv_data, data2.mv_data, data.mv_size), 0);

    int8_t destination;
    serializer.deserialize(data, destination);

    EXPECT_EQ(source, destination);

    int8_t dest2 = serializer.deserialize(data);

    EXPECT_EQ(source, dest2);
}

TEST(Serialization, Int16) {
    int16_t source = -3469;
    LMDBAL::Serializer<int16_t> serializer;
    LMDBAL::Serializer<int16_t> serializer2(source);
    LMDBAL::Serializer<int16_t> deserializer;

    serializer.setData(source);
    MDB_val data = serializer.getData();
    MDB_val data2 = serializer2.getData();

    EXPECT_EQ(data.mv_size, data2.mv_size);
    EXPECT_EQ(std::memcmp(data.mv_data, data2.mv_data, data.mv_size), 0);

    int16_t destination;
    serializer.deserialize(data, destination);

    EXPECT_EQ(source, destination);

    int16_t dest2 = serializer.deserialize(data);

    EXPECT_EQ(source, dest2);
}

TEST(Serialization, Int32) {
    int32_t source = 454832;
    LMDBAL::Serializer<int32_t> serializer;
    LMDBAL::Serializer<int32_t> serializer2(source);
    LMDBAL::Serializer<int32_t> deserializer;

    serializer.setData(source);
    MDB_val data = serializer.getData();
    MDB_val data2 = serializer2.getData();

    EXPECT_EQ(data.mv_size, data2.mv_size);
    EXPECT_EQ(std::memcmp(data.mv_data, data2.mv_data, data.mv_size), 0);

    int32_t destination;
    serializer.deserialize(data, destination);

    EXPECT_EQ(source, destination);

    int32_t dest2 = serializer.deserialize(data);

    EXPECT_EQ(source, dest2);
}

TEST(Serialization, Int64) {
    int64_t source = -875525478136;
    LMDBAL::Serializer<int64_t> serializer;
    LMDBAL::Serializer<int64_t> serializer2(source);
    LMDBAL::Serializer<int64_t> deserializer;

    serializer.setData(source);
    MDB_val data = serializer.getData();
    MDB_val data2 = serializer2.getData();

    EXPECT_EQ(data.mv_size, data2.mv_size);
    EXPECT_EQ(std::memcmp(data.mv_data, data2.mv_data, data.mv_size), 0);

    int64_t destination;
    serializer.deserialize(data, destination);

    EXPECT_EQ(source, destination);

    int64_t dest2 = serializer.deserialize(data);

    EXPECT_EQ(source, dest2);
}

TEST(Serialization, UInt8) {
    uint8_t source = 196;
    LMDBAL::Serializer<uint8_t> serializer;
    LMDBAL::Serializer<uint8_t> serializer2(source);
    LMDBAL::Serializer<uint8_t> deserializer;

    serializer.setData(source);
    MDB_val data = serializer.getData();
    MDB_val data2 = serializer2.getData();

    EXPECT_EQ(data.mv_size, data2.mv_size);
    EXPECT_EQ(std::memcmp(data.mv_data, data2.mv_data, data.mv_size), 0);

    uint8_t destination;
    serializer.deserialize(data, destination);

    EXPECT_EQ(source, destination);

    uint8_t dest2 = serializer.deserialize(data);

    EXPECT_EQ(source, dest2);
}

TEST(Serialization, UInt16) {
    uint16_t source = 8634;
    LMDBAL::Serializer<uint16_t> serializer;
    LMDBAL::Serializer<uint16_t> serializer2(source);
    LMDBAL::Serializer<uint16_t> deserializer;

    serializer.setData(source);
    MDB_val data = serializer.getData();
    MDB_val data2 = serializer2.getData();

    EXPECT_EQ(data.mv_size, data2.mv_size);
    EXPECT_EQ(std::memcmp(data.mv_data, data2.mv_data, data.mv_size), 0);

    uint16_t destination;
    serializer.deserialize(data, destination);

    EXPECT_EQ(source, destination);

    uint16_t dest2 = serializer.deserialize(data);

    EXPECT_EQ(source, dest2);
}

TEST(Serialization, UInt32) {
    uint32_t source = 115469;
    LMDBAL::Serializer<uint32_t> serializer;
    LMDBAL::Serializer<uint32_t> serializer2(source);
    LMDBAL::Serializer<uint32_t> deserializer;

    serializer.setData(source);
    MDB_val data = serializer.getData();
    MDB_val data2 = serializer2.getData();

    EXPECT_EQ(data.mv_size, data2.mv_size);
    EXPECT_EQ(std::memcmp(data.mv_data, data2.mv_data, data.mv_size), 0);

    uint32_t destination;
    serializer.deserialize(data, destination);

    EXPECT_EQ(source, destination);

    uint32_t dest2 = serializer.deserialize(data);

    EXPECT_EQ(source, dest2);
}

TEST(Serialization, UInt64) {
    uint64_t source = 498763546873;
    LMDBAL::Serializer<uint64_t> serializer;
    LMDBAL::Serializer<uint64_t> serializer2(source);
    LMDBAL::Serializer<uint64_t> deserializer;

    serializer.setData(source);
    MDB_val data = serializer.getData();
    MDB_val data2 = serializer2.getData();

    EXPECT_EQ(data.mv_size, data2.mv_size);
    EXPECT_EQ(std::memcmp(data.mv_data, data2.mv_data, data.mv_size), 0);

    uint64_t destination;
    serializer.deserialize(data, destination);

    EXPECT_EQ(source, destination);

    uint64_t dest2 = serializer.deserialize(data);

    EXPECT_EQ(source, dest2);
}

TEST(Serialization, StdString) {
    std::string source("days just go by, some good and some are bad");
    LMDBAL::Serializer<std::string> serializer;
    LMDBAL::Serializer<std::string> serializer2(source);
    LMDBAL::Serializer<std::string> deserializer;

    serializer.setData(source);
    MDB_val data = serializer.getData();
    MDB_val data2 = serializer2.getData();

    EXPECT_EQ(data.mv_size, data2.mv_size);
    EXPECT_EQ(std::memcmp(data.mv_data, data2.mv_data, data.mv_size), 0);

    std::string destination;
    serializer.deserialize(data, destination);

    EXPECT_EQ(source, destination);

    std::string dest2 = serializer.deserialize(data);

    EXPECT_EQ(source, dest2);
}

TEST(Serialization, QString) {
    QString source("may be will find nothing new, may be I'll end up just just like you");
    LMDBAL::Serializer<QString> serializer;
    LMDBAL::Serializer<QString> serializer2(source);
    LMDBAL::Serializer<QString> deserializer;

    serializer.setData(source);
    MDB_val data = serializer.getData();
    MDB_val data2 = serializer2.getData();

    EXPECT_EQ(data.mv_size, data2.mv_size);
    EXPECT_EQ(std::memcmp(data.mv_data, data2.mv_data, data.mv_size), 0);

    QString destination;
    serializer.deserialize(data, destination);

    EXPECT_EQ(source, destination);

    QString dest2 = serializer.deserialize(data);

    EXPECT_EQ(source, dest2);
}

TEST(Serialization, QByteArray) {
    QByteArray source = QByteArray::fromHex("84 be 81 6c d3 5e c3 49 94 51 6f 8f a7 3b 0c d8 29 23 a3 21 4d b8 3f 73");
    LMDBAL::Serializer<QByteArray> serializer;
    LMDBAL::Serializer<QByteArray> serializer2(source);
    LMDBAL::Serializer<QByteArray> deserializer;

    serializer.setData(source);
    MDB_val data = serializer.getData();
    MDB_val data2 = serializer2.getData();

    EXPECT_EQ(data.mv_size, data2.mv_size);
    EXPECT_EQ(std::memcmp(data.mv_data, data2.mv_data, data.mv_size), 0);

    QByteArray destination;
    serializer.deserialize(data, destination);

    EXPECT_EQ(source, destination);

    QByteArray dest2 = serializer.deserialize(data);

    EXPECT_EQ(source, dest2);
}

TEST(Serialization, StdMap) {
    std::map<uint16_t, uint8_t> source({
        {467, 123},
        {1397, 8},
        {551, -9},
        {864, 114},
        {9615, -85},
        {32, 32}
    });
    LMDBAL::Serializer<std::map<uint16_t, uint8_t>> serializer;
    LMDBAL::Serializer<std::map<uint16_t, uint8_t>> serializer2(source);
    LMDBAL::Serializer<std::map<uint16_t, uint8_t>> deserializer;

    serializer.setData(source);
    MDB_val data = serializer.getData();
    MDB_val data2 = serializer2.getData();

    EXPECT_EQ(data.mv_size, data2.mv_size);
    EXPECT_EQ(std::memcmp(data.mv_data, data2.mv_data, data.mv_size), 0);

    std::map<uint16_t, uint8_t> destination;
    serializer.deserialize(data, destination);

    EXPECT_EQ(source, destination);

    std::map<uint16_t, uint8_t> dest2 = serializer.deserialize(data);

    EXPECT_EQ(source, dest2);
}