#include <gtest/gtest.h>

#include "snowflake.h"

TEST(SNOWFLAKE, GENERATE)
{
    uint16_t thread_id = 1;
    uint8_t worker_base_id = 2;
    uint8_t worker_offset_id = 3;

    struct snowflake *sf = snowflake_new(thread_id, worker_base_id, worker_offset_id);
    EXPECT_TRUE(sf != NULL);
    EXPECT_TRUE(snowflake_generate(sf, 1000) != 0);
    snowflake_free(sf);
}

TEST(SNOWFLAKE, DESERIALIZE)
{
    uint16_t thread_id = 1;
    uint8_t worker_base_id = 2;
    uint8_t worker_offset_id = 3;

    struct snowflake *sf = snowflake_new(thread_id, worker_base_id, worker_offset_id);
    EXPECT_TRUE(sf != NULL);

    for (uint64_t i = 0; i < 5; i++)
    {
        uint64_t id = snowflake_generate(sf, i + 1000);
        EXPECT_TRUE(id != 0);

        struct snowflake_meta meta = {};
        snowflake_deserialize(id, &meta);
        EXPECT_EQ(meta.sequence, i);
        EXPECT_EQ(meta.time_relative, i + 1000);
        EXPECT_EQ(meta.thread_id, thread_id);
        EXPECT_EQ(meta.device_id, (worker_base_id << 7) | worker_offset_id);
        EXPECT_EQ(meta.worker_base_id, worker_base_id);
        EXPECT_EQ(meta.worker_offset_id, worker_offset_id);
    }

    snowflake_free(sf);
}

int main(int argc, char **argv)
{
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
