struct CoolEvent
{
    int m_value;
};

struct EventCounter
{
    int m_eventCount = 0;
    int m_valueSum = 0;

    void onEvent(const CoolEvent& a_event)
    {
        m_eventCount++;
        m_valueSum += a_event.m_value;
    }
};

/// Tests the event system calls a single listener the appropriate amount of times with the correct data in the event
/// Also makes sure that when the listener is removed, the events aren't sent to that listener anymore and that adding it back makes it behave the same as it did before
TEST(EventSystemTests, SingleEventSingleListener)
{
    //setup even system and counter
    tds::EventSystem eventSystem;
    EventCounter eventCounter;
    eventSystem.addListener<CoolEvent>(eventCounter);

    //start emitting events and asserting the values
    ASSERT_EQ(eventCounter.m_eventCount, 0);
    ASSERT_EQ(eventCounter.m_valueSum, 0);
    eventSystem.emitEvent(CoolEvent{ 5 });
    ASSERT_EQ(eventCounter.m_eventCount, 1);
    ASSERT_EQ(eventCounter.m_valueSum, 5);
    eventSystem.emitEvent(CoolEvent{ 99 });
    ASSERT_EQ(eventCounter.m_eventCount, 2);
    ASSERT_EQ(eventCounter.m_valueSum, 104);
    eventSystem.emitEvent(CoolEvent{ -88 });
    ASSERT_EQ(eventCounter.m_eventCount, 3);
    ASSERT_EQ(eventCounter.m_valueSum, 16);
    eventSystem.emitEvent(CoolEvent{ 48 });
    ASSERT_EQ(eventCounter.m_eventCount, 4);
    ASSERT_EQ(eventCounter.m_valueSum, 64);

    //reset the counter but leave the sum the same
    eventCounter.m_eventCount = 0;
    ASSERT_EQ(eventCounter.m_eventCount, 0);
    ASSERT_EQ(eventCounter.m_valueSum, 64);
    eventSystem.emitEvent(CoolEvent{ 108 });
    ASSERT_EQ(eventCounter.m_eventCount, 1);
    ASSERT_EQ(eventCounter.m_valueSum, 172);
    eventSystem.emitEvent(CoolEvent{ -32 });
    ASSERT_EQ(eventCounter.m_eventCount, 2);
    ASSERT_EQ(eventCounter.m_valueSum, 140);

    //reset the sum but leave the counter the same
    eventCounter.m_valueSum = 0;
    ASSERT_EQ(eventCounter.m_eventCount, 2);
    ASSERT_EQ(eventCounter.m_valueSum, 0);
    eventSystem.emitEvent(CoolEvent{ 89 });
    ASSERT_EQ(eventCounter.m_eventCount, 3);
    ASSERT_EQ(eventCounter.m_valueSum, 89);
    eventSystem.emitEvent(CoolEvent{ 204 });
    ASSERT_EQ(eventCounter.m_eventCount, 4);
    ASSERT_EQ(eventCounter.m_valueSum, 293);

    //reset both counter and value
    eventCounter.m_valueSum = 0;
    eventCounter.m_eventCount = 0;
    ASSERT_EQ(eventCounter.m_eventCount, 0);
    ASSERT_EQ(eventCounter.m_valueSum, 0);
    eventSystem.emitEvent(CoolEvent{ 5 });
    ASSERT_EQ(eventCounter.m_eventCount, 1);
    ASSERT_EQ(eventCounter.m_valueSum, 5);
    eventSystem.emitEvent(CoolEvent{ 99 });
    ASSERT_EQ(eventCounter.m_eventCount, 2);
    ASSERT_EQ(eventCounter.m_valueSum, 104);
    eventSystem.emitEvent(CoolEvent{ -88 });
    ASSERT_EQ(eventCounter.m_eventCount, 3);
    ASSERT_EQ(eventCounter.m_valueSum, 16);
    eventSystem.emitEvent(CoolEvent{ 48 });
    ASSERT_EQ(eventCounter.m_eventCount, 4);
    ASSERT_EQ(eventCounter.m_valueSum, 64);

    //remove from listeners
    eventSystem.removeListener<CoolEvent>(eventCounter);
    ASSERT_EQ(eventCounter.m_eventCount, 4);
    ASSERT_EQ(eventCounter.m_valueSum, 64);
    eventSystem.emitEvent(CoolEvent{ 5 });
    ASSERT_EQ(eventCounter.m_eventCount, 4);
    ASSERT_EQ(eventCounter.m_valueSum, 64);
    eventSystem.emitEvent(CoolEvent{ 99 });
    ASSERT_EQ(eventCounter.m_eventCount, 4);
    ASSERT_EQ(eventCounter.m_valueSum, 64);
    eventSystem.emitEvent(CoolEvent{ -88 });
    ASSERT_EQ(eventCounter.m_eventCount, 4);
    ASSERT_EQ(eventCounter.m_valueSum, 64);
    eventSystem.emitEvent(CoolEvent{ -48 });
    ASSERT_EQ(eventCounter.m_eventCount, 4);
    ASSERT_EQ(eventCounter.m_valueSum, 64);

    //add back to listeners again
    eventSystem.addListener<CoolEvent>(eventCounter);
    ASSERT_EQ(eventCounter.m_eventCount, 4);
    ASSERT_EQ(eventCounter.m_valueSum, 64);
    eventSystem.emitEvent(CoolEvent{ 5 });
    ASSERT_EQ(eventCounter.m_eventCount, 5);
    ASSERT_EQ(eventCounter.m_valueSum, 69);
    eventSystem.emitEvent(CoolEvent{ 99 });
    ASSERT_EQ(eventCounter.m_eventCount, 6);
    ASSERT_EQ(eventCounter.m_valueSum, 168);
    eventSystem.emitEvent(CoolEvent{ -88 });
    ASSERT_EQ(eventCounter.m_eventCount, 7);
    ASSERT_EQ(eventCounter.m_valueSum, 80);
    eventSystem.emitEvent(CoolEvent{ -48 });
    ASSERT_EQ(eventCounter.m_eventCount, 8);
    ASSERT_EQ(eventCounter.m_valueSum, 32);

}