/*
 *
 *    Copyright (c) 2020-2021 Project CHIP Authors
 *    Copyright (c) 2016-2017 Nest Labs, Inc.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 *    @file
 *      This is a unit test suite for <tt>chip::System::Timer</tt>,
 *      the part of the CHIP System Layer that implements timers.
 *
 */

#include <errno.h>
#include <stdint.h>
#include <string.h>

#include <gtest/gtest.h>

#include <lib/core/ErrorStr.h>
#include <lib/support/CodeUtils.h>
#include <system/SystemConfig.h>
#include <system/SystemError.h>
#include <system/SystemLayerImpl.h>

#if CHIP_SYSTEM_CONFIG_USE_LWIP
#include <lwip/init.h>
#include <lwip/sys.h>
#include <lwip/tcpip.h>
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP

using chip::ErrorStr;
using namespace chip::System;

template <class LayerImpl, typename Enable = void>
class LayerEvents
{
public:
    static bool HasServiceEvents() { return false; }
    static void ServiceEvents(Layer & aLayer) {}
};

#if CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK

template <class LayerImpl>
class LayerEvents<LayerImpl, typename std::enable_if<std::is_base_of<LayerSocketsLoop, LayerImpl>::value>::type>
{
public:
    static bool HasServiceEvents() { return true; }
    static void ServiceEvents(Layer & aLayer)
    {
        LayerSocketsLoop & layer = static_cast<LayerSocketsLoop &>(aLayer);
        layer.PrepareEvents();
        layer.WaitForEvents();
        layer.HandleEvents();
    }
};

#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS || CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK

#if CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT

template <class LayerImpl>
class LayerEvents<LayerImpl, typename std::enable_if<std::is_base_of<LayerImplFreeRTOS, LayerImpl>::value>::type>
{
public:
    static bool HasServiceEvents() { return true; }
    static void ServiceEvents(Layer & aLayer)
    {
        LayerImplFreeRTOS & layer = static_cast<LayerImplFreeRTOS &>(aLayer);
        if (layer.IsInitialized())
        {
            layer.HandlePlatformTimer();
        }
    }
};

#endif // CHIP_SYSTEM_CONFIG_USE_LWIP || CHIP_SYSTEM_CONFIG_USE_OPEN_THREAD_ENDPOINT

// Test input vector format.
static const uint32_t MAX_NUM_TIMERS = 1000;

namespace chip {
namespace System {

class TestSystemTimer : public ::testing::Test
{
public:
    static void SetUpTestSuite()
    {
        ASSERT_EQ(::chip::Platform::MemoryInit(), CHIP_NO_ERROR);

#if CHIP_SYSTEM_CONFIG_USE_LWIP && (LWIP_VERSION_MAJOR == 2) && (LWIP_VERSION_MINOR == 0) && !(CHIP_SYSTEM_CONFIG_LWIP_SKIP_INIT)
        static sys_mbox_t * sLwIPEventQueue = NULL;
        sys_mbox_new(sLwIPEventQueue, 100);
        tcpip_init(NULL, NULL);
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP && (LWIP_VERSION_MAJOR == 2) && (LWIP_VERSION_MINOR == 0) &&
       // !(CHIP_SYSTEM_CONFIG_LWIP_SKIP_INIT)

        mLayer.Init();
    }

    static void TearDownTestSuite()
    {
        mLayer.Shutdown();

#if CHIP_SYSTEM_CONFIG_USE_LWIP && (LWIP_VERSION_MAJOR == 2) && (LWIP_VERSION_MINOR == 0) && !(CHIP_SYSTEM_CONFIG_LWIP_SKIP_INIT)
        tcpip_finish(NULL, NULL);
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP && (LWIP_VERSION_MAJOR == 2) && (LWIP_VERSION_MINOR == 0) &&
       // !(CHIP_SYSTEM_CONFIG_LWIP_SKIP_INIT)

        ::chip::Platform::MemoryShutdown();
    }

    template <typename T>
    static auto GetTimerPoolObject(T && pool)
    {
        return pool.mTimerPool;
    }

    static LayerImpl mLayer;
};

LayerImpl TestSystemTimer::mLayer;

static TestSystemTimer * gCurrentTestContext = nullptr;

class ScopedGlobalTestContext
{
public:
    ScopedGlobalTestContext(TestSystemTimer * ctx) { gCurrentTestContext = ctx; }
    ~ScopedGlobalTestContext() { gCurrentTestContext = nullptr; }
};

static volatile bool sOverflowTestDone;

void TimerFailed(void * aState)
{
    sOverflowTestDone = true;
    FAIL() << "Timer failed";
}

void HandleTimerFailed(Layer * systemLayer, void * aState)
{
    (void) systemLayer;
    TimerFailed(aState);
}

void HandleTimer10Success(Layer * systemLayer, void * aState)
{
    EXPECT_TRUE(true);
    sOverflowTestDone = true;
}

TEST_F(TestSystemTimer, CheckOverflow)
{
    if (!LayerEvents<LayerImpl>::HasServiceEvents())
        return;

    chip::System::Clock::Milliseconds32 timeout_overflow_0ms = chip::System::Clock::Milliseconds32(652835029);
    chip::System::Clock::Milliseconds32 timeout_10ms         = chip::System::Clock::Milliseconds32(10);

    Layer & lSys = mLayer;

    sOverflowTestDone = false;

    lSys.StartTimer(timeout_overflow_0ms, HandleTimerFailed, this);
    lSys.StartTimer(timeout_10ms, HandleTimer10Success, this);

    while (!sOverflowTestDone)
    {
        LayerEvents<LayerImpl>::ServiceEvents(lSys);
    }

    lSys.CancelTimer(HandleTimerFailed, this);
    // cb  timer is cancelled by destructor
    lSys.CancelTimer(HandleTimer10Success, this);
}

void HandleGreedyTimer(Layer * aLayer, void * aState)
{
    static uint32_t sNumTimersHandled = 0;
    EXPECT_LT(sNumTimersHandled, MAX_NUM_TIMERS);

    if (sNumTimersHandled >= MAX_NUM_TIMERS)
    {
        return;
    }

    aLayer->StartTimer(chip::System::Clock::kZero, HandleGreedyTimer, aState);
    sNumTimersHandled++;
}

TEST_F(TestSystemTimer, CheckStarvation)
{
    if (!LayerEvents<LayerImpl>::HasServiceEvents())
        return;

    Layer & lSys = mLayer;

    lSys.StartTimer(chip::System::Clock::kZero, HandleGreedyTimer, this);

    LayerEvents<LayerImpl>::ServiceEvents(lSys);
}

TEST_F(TestSystemTimer, CheckOrder)
{
    if (!LayerEvents<LayerImpl>::HasServiceEvents())
        return;

    Layer & systemLayer = mLayer;

    struct TestState
    {
        void Record(char c)
        {
            size_t n = strlen(record);
            if (n + 1 < sizeof(record))
            {
                record[n++] = c;
                record[n]   = 0;
            }
        }
        static void A(Layer * layer, void * state) { static_cast<TestState *>(state)->Record('A'); }
        static void B(Layer * layer, void * state) { static_cast<TestState *>(state)->Record('B'); }
        static void C(Layer * layer, void * state) { static_cast<TestState *>(state)->Record('C'); }
        static void D(Layer * layer, void * state) { static_cast<TestState *>(state)->Record('D'); }
        char record[5] = { 0 };
    };
    TestState testState;
    EXPECT_EQ(testState.record[0], 0);

    Clock::ClockBase * const savedClock = &SystemClock();
    Clock::Internal::MockClock mockClock;
    Clock::Internal::SetSystemClockForTesting(&mockClock);

    using namespace Clock::Literals;
    systemLayer.StartTimer(300_ms, TestState::D, &testState);
    systemLayer.StartTimer(100_ms, TestState::B, &testState);
    systemLayer.StartTimer(200_ms, TestState::C, &testState);
    systemLayer.StartTimer(0_ms, TestState::A, &testState);

    LayerEvents<LayerImpl>::ServiceEvents(systemLayer);
    EXPECT_EQ(strcmp(testState.record, "A"), 0);

    mockClock.AdvanceMonotonic(100_ms);
    LayerEvents<LayerImpl>::ServiceEvents(systemLayer);
    EXPECT_EQ(strcmp(testState.record, "AB"), 0);

    mockClock.AdvanceMonotonic(200_ms);
    LayerEvents<LayerImpl>::ServiceEvents(systemLayer);
    EXPECT_EQ(strcmp(testState.record, "ABCD"), 0);

    Clock::Internal::SetSystemClockForTesting(savedClock);
}

TEST_F(TestSystemTimer, CheckCancellation)
{
    if (!LayerEvents<LayerImpl>::HasServiceEvents())
        return;

    Layer & systemLayer = mLayer;

    struct TestState
    {
        TestState(Layer & aSystemLayer) : mSystemLayer(aSystemLayer) {}

        void Record(char c)
        {
            size_t n = strlen(record);
            if (n + 1 < sizeof(record))
            {
                record[n++] = c;
                record[n]   = 0;
            }
        }
        static void A(Layer * layer, void * state)
        {
            auto self = static_cast<TestState *>(state);
            self->Record('A');
            self->mSystemLayer.CancelTimer(B, state);
            self->mSystemLayer.CancelTimer(D, state);
        }
        static void B(Layer * layer, void * state) { static_cast<TestState *>(state)->Record('B'); }
        static void C(Layer * layer, void * state)
        {
            auto self = static_cast<TestState *>(state);
            self->Record('C');
            self->mSystemLayer.CancelTimer(E, state);
        }
        static void D(Layer * layer, void * state) { static_cast<TestState *>(state)->Record('D'); }
        static void E(Layer * layer, void * state) { static_cast<TestState *>(state)->Record('E'); }
        char record[6] = { 0 };

        Layer & mSystemLayer;
    };
    TestState testState(systemLayer);
    EXPECT_EQ(testState.record[0], 0);

    Clock::ClockBase * const savedClock = &SystemClock();
    Clock::Internal::MockClock mockClock;
    Clock::Internal::SetSystemClockForTesting(&mockClock);

    using namespace Clock::Literals;
    systemLayer.StartTimer(0_ms, TestState::A, &testState);
    systemLayer.StartTimer(0_ms, TestState::B, &testState);
    systemLayer.StartTimer(20_ms, TestState::C, &testState);
    systemLayer.StartTimer(30_ms, TestState::D, &testState);
    systemLayer.StartTimer(50_ms, TestState::E, &testState);

    mockClock.AdvanceMonotonic(100_ms);
    LayerEvents<LayerImpl>::ServiceEvents(systemLayer);
    EXPECT_EQ(strcmp(testState.record, "AC"), 0);

    Clock::Internal::SetSystemClockForTesting(savedClock);
}

namespace {

namespace CancelTimerTest {

// A bit lower than maximum system timers just in case, for systems that
// have some form of limit
constexpr unsigned kCancelTimerCount = CHIP_SYSTEM_CONFIG_NUM_TIMERS - 4;
int gCallbackProcessed[kCancelTimerCount];

/// Validates that gCallbackProcessed has valid values (0 or 1)
void ValidateExecutedTimerCounts()
{
    for (int processed : gCallbackProcessed)
    {
        EXPECT_TRUE((processed == 0) || (processed == 1));
    }
}

unsigned ExecutedTimerCount()
{
    unsigned count = 0;
    for (int processed : gCallbackProcessed)
    {
        if (processed != 0)
        {
            count++;
        }
    }
    return count;
}

void Callback(Layer * layer, void * state)
{
    unsigned idx = static_cast<unsigned>(reinterpret_cast<uintptr_t>(state));
    if (gCallbackProcessed[idx] != 0)
    {
        ChipLogError(Test, "UNEXPECTED EXECUTION at index %u", idx);
    }

    gCallbackProcessed[idx]++;

    if (ExecutedTimerCount() == kCancelTimerCount / 2)
    {
        ChipLogProgress(Test, "Cancelling timers");
        for (unsigned i = 0; i < kCancelTimerCount; i++)
        {
            if (gCallbackProcessed[i] != 0)
            {
                continue;
            }
            ChipLogProgress(Test, "Timer %u is being cancelled", i);
            gCurrentTestContext->mLayer.CancelTimer(Callback, reinterpret_cast<void *>(static_cast<uintptr_t>(i)));
            gCallbackProcessed[i]++; // pretend executed.
        }
    }
}

TEST_F(TestSystemTimer, CancelTimerTest)
{
    // Validates that timers can cancel other timers. Generally the test will
    // do the following:
    //   - schedule several timers to start at the same time
    //   - within each timers, after half of them have run, make one timer
    //     cancel all the other ones
    //   - assert that:
    //       - timers will run if scheduled
    //       - once cancelled, timers will NOT run (i.e. a timer can cancel
    //         other timers, even if they are expiring at the same time)
    memset(gCallbackProcessed, 0, sizeof(gCallbackProcessed));

    // TestContext & testContext = *static_cast<TestContext *>(aContext);
    // ScopedGlobalTestContext testScope(&testContext);

    Layer & systemLayer = mLayer;

    Clock::ClockBase * const savedClock = &SystemClock();
    Clock::Internal::MockClock mockClock;
    Clock::Internal::SetSystemClockForTesting(&mockClock);
    using namespace Clock::Literals;

    for (unsigned i = 0; i < kCancelTimerCount; i++)
    {
        EXPECT_EQ(systemLayer.StartTimer(10_ms, Callback, reinterpret_cast<void *>(static_cast<uintptr_t>(i))), CHIP_NO_ERROR);
    }

    LayerEvents<LayerImpl>::ServiceEvents(systemLayer);
    ValidateExecutedTimerCounts();
    EXPECT_EQ(ExecutedTimerCount(), 0U);

    mockClock.AdvanceMonotonic(20_ms);
    LayerEvents<LayerImpl>::ServiceEvents(systemLayer);

    ValidateExecutedTimerCounts();
    EXPECT_EQ(ExecutedTimerCount(), kCancelTimerCount);

    Clock::Internal::SetSystemClockForTesting(savedClock);
}

} // namespace CancelTimerTest
} // namespace

// Test the implementation helper classes TimerPool, TimerList, and TimerData.
TEST_F(TestSystemTimer, CheckTimerPool)
{
    using Timer = TimerList::Node;
    struct TestState
    {
        int count = 0;
        static void Increment(Layer * layer, void * state) { ++static_cast<TestState *>(state)->count; }
        static void Reset(Layer * layer, void * state) { static_cast<TestState *>(state)->count = 0; }
    };
    TestState testState;

    using namespace Clock::Literals;
    struct
    {
        Clock::Timestamp awakenTime;
        TimerCompleteCallback onComplete;
        Timer * timer;
    } testTimer[] = {
        { 111_ms, TestState::Increment }, // 0
        { 100_ms, TestState::Increment }, // 1
        { 202_ms, TestState::Reset },     // 2
        { 303_ms, TestState::Increment }, // 3
    };

    TimerPool<Timer> pool;
    EXPECT_EQ(pool.mTimerPool.Allocated(), 0U);
    SYSTEM_STATS_RESET(Stats::kSystemLayer_NumTimers);
    SYSTEM_STATS_RESET_HIGH_WATER_MARK_FOR_TESTING(Stats::kSystemLayer_NumTimers);
    EXPECT_TRUE(SYSTEM_STATS_TEST_IN_USE(Stats::kSystemLayer_NumTimers, 0));
    EXPECT_TRUE(SYSTEM_STATS_TEST_HIGH_WATER_MARK(Stats::kSystemLayer_NumTimers, 0));

    // Test TimerPool::Create() and TimerData accessors.

    for (auto & timer : testTimer)
    {
        timer.timer = pool.Create(mLayer, timer.awakenTime, timer.onComplete, &testState);
    }
    EXPECT_TRUE(SYSTEM_STATS_TEST_IN_USE(Stats::kSystemLayer_NumTimers, 4));

    for (auto & timer : testTimer)
    {
        ASSERT_NE(timer.timer, nullptr);
        EXPECT_EQ(timer.timer->AwakenTime(), timer.awakenTime);
        // TODO: Fix casting and use EXPECT_EQ
        EXPECT_TRUE(timer.timer->GetCallback().GetOnComplete() == timer.onComplete);
        EXPECT_EQ(timer.timer->GetCallback().GetAppState(), &testState);
        EXPECT_EQ(timer.timer->GetCallback().GetSystemLayer(), &mLayer);
    }

    // Test TimerList operations.

    TimerList list;
    EXPECT_EQ(list.Remove(nullptr), nullptr);
    EXPECT_EQ(list.Remove(nullptr, nullptr), nullptr);
    EXPECT_EQ(list.PopEarliest(), nullptr);
    EXPECT_EQ(list.PopIfEarlier(500_ms), nullptr);
    EXPECT_EQ(list.Earliest(), nullptr);
    EXPECT_TRUE(list.Empty());

    Timer * earliest = list.Add(testTimer[0].timer); // list: () → (0) returns: 0
    EXPECT_EQ(earliest, testTimer[0].timer);
    EXPECT_EQ(list.PopIfEarlier(10_ms), nullptr);
    EXPECT_EQ(list.Earliest(), testTimer[0].timer);
    EXPECT_FALSE(list.Empty());

    earliest = list.Add(testTimer[1].timer); // list: (0) → (1 0) returns: 1
    EXPECT_EQ(earliest, testTimer[1].timer);
    EXPECT_EQ(list.Earliest(), testTimer[1].timer);

    earliest = list.Add(testTimer[2].timer); // list: (1 0) → (1 0 2) returns: 1
    EXPECT_EQ(earliest, testTimer[1].timer);
    EXPECT_EQ(list.Earliest(), testTimer[1].timer);

    earliest = list.Add(testTimer[3].timer); // list: (1 0 2) → (1 0 2 3) returns: 1
    EXPECT_EQ(earliest, testTimer[1].timer);
    EXPECT_EQ(list.Earliest(), testTimer[1].timer);

    earliest = list.Remove(earliest); // list: (1 0 2 3) → (0 2 3) returns: 0
    EXPECT_EQ(earliest, testTimer[0].timer);
    EXPECT_EQ(list.Earliest(), testTimer[0].timer);

    earliest = list.Remove(TestState::Reset, &testState); // list: (0 2 3) → (0 3) returns: 2
    EXPECT_EQ(earliest, testTimer[2].timer);
    EXPECT_EQ(list.Earliest(), testTimer[0].timer);

    earliest = list.PopEarliest(); // list: (0 3) → (3) returns: 0
    EXPECT_EQ(earliest, testTimer[0].timer);
    EXPECT_EQ(list.Earliest(), testTimer[3].timer);

    earliest = list.PopIfEarlier(10_ms); // list: (3) → (3) returns: nullptr
    EXPECT_EQ(earliest, nullptr);

    earliest = list.PopIfEarlier(500_ms); // list: (3) → () returns: 3
    EXPECT_EQ(earliest, testTimer[3].timer);
    EXPECT_TRUE(list.Empty());

    earliest = list.Add(testTimer[3].timer); // list: () → (3) returns: 3
    list.Clear();                            // list: (3) → ()
    EXPECT_EQ(earliest, testTimer[3].timer);
    EXPECT_TRUE(list.Empty());

    for (auto & timer : testTimer)
    {
        list.Add(timer.timer);
    }
    TimerList early = list.ExtractEarlier(200_ms); // list: (1 0 2 3) → (2 3) returns: (1 0)
    EXPECT_EQ(list.PopEarliest(), testTimer[2].timer);
    EXPECT_EQ(list.PopEarliest(), testTimer[3].timer);
    EXPECT_EQ(list.PopEarliest(), nullptr);
    EXPECT_EQ(early.PopEarliest(), testTimer[1].timer);
    EXPECT_EQ(early.PopEarliest(), testTimer[0].timer);
    EXPECT_EQ(early.PopEarliest(), nullptr);

    // Test TimerPool::Invoke()
    EXPECT_EQ(testState.count, 0);
    pool.Invoke(testTimer[0].timer);
    testTimer[0].timer = nullptr;
    EXPECT_EQ(testState.count, 1);
    EXPECT_EQ(pool.mTimerPool.Allocated(), 3U);
    EXPECT_TRUE(SYSTEM_STATS_TEST_IN_USE(Stats::kSystemLayer_NumTimers, 3));

    // Test TimerPool::Release()
    pool.Release(testTimer[1].timer);
    testTimer[1].timer = nullptr;
    EXPECT_EQ(testState.count, 1);
    EXPECT_EQ(pool.mTimerPool.Allocated(), 2U);
    EXPECT_TRUE(SYSTEM_STATS_TEST_IN_USE(Stats::kSystemLayer_NumTimers, 2));

    pool.ReleaseAll();
    EXPECT_EQ(pool.mTimerPool.Allocated(), 0U);
    EXPECT_TRUE(SYSTEM_STATS_TEST_IN_USE(Stats::kSystemLayer_NumTimers, 0));
    EXPECT_TRUE(SYSTEM_STATS_TEST_HIGH_WATER_MARK(Stats::kSystemLayer_NumTimers, 4));
}

TEST_F(TestSystemTimer, ExtendTimerToTest)
{
    if (!LayerEvents<LayerImpl>::HasServiceEvents())
        return;

    Layer & systemLayer = mLayer;

    struct TestState
    {
        void Record(char c)
        {
            size_t n = strlen(record);
            if (n + 1 < sizeof(record))
            {
                record[n++] = c;
                record[n]   = 0;
            }
        }
        static void A(Layer * layer, void * state) { static_cast<TestState *>(state)->Record('A'); }
        static void B(Layer * layer, void * state) { static_cast<TestState *>(state)->Record('B'); }
        static void C(Layer * layer, void * state) { static_cast<TestState *>(state)->Record('C'); }
        static void D(Layer * layer, void * state) { static_cast<TestState *>(state)->Record('D'); }
        char record[5] = { 0 };
    };
    TestState testState;
    EXPECT_EQ(testState.record[0], 0);

    Clock::ClockBase * const savedClock = &SystemClock();
    Clock::Internal::MockClock mockClock;
    Clock::Internal::SetSystemClockForTesting(&mockClock);

    using namespace Clock::Literals;
    systemLayer.StartTimer(150_ms, TestState::B, &testState);
    systemLayer.StartTimer(200_ms, TestState::C, &testState);
    systemLayer.StartTimer(150_ms, TestState::D, &testState);

    // Timer wasn't started before. ExtendTimerTo will start it.
    systemLayer.ExtendTimerTo(100_ms, TestState::A, &testState);
    mockClock.AdvanceMonotonic(100_ms);
    LayerEvents<LayerImpl>::ServiceEvents(systemLayer);
    EXPECT_EQ(strcmp(testState.record, "A"), 0);

    // Timer B as 50ms remaining. ExtendTimerTo 25 should have no effect
    // Timer C as 100ms remaining. ExtendTimerTo 75ms should have no effect
    // Timer D as 50ms remaining. Timer should be extend to a duration of 75ms
    systemLayer.ExtendTimerTo(25_ms, TestState::B, &testState);
    systemLayer.ExtendTimerTo(75_ms, TestState::D, &testState);
    systemLayer.ExtendTimerTo(75_ms, TestState::D, &testState);

    mockClock.AdvanceMonotonic(25_ms);
    LayerEvents<LayerImpl>::ServiceEvents(systemLayer);
    EXPECT_EQ(strcmp(testState.record, "A"), 0);

    mockClock.AdvanceMonotonic(25_ms);
    LayerEvents<LayerImpl>::ServiceEvents(systemLayer);
    EXPECT_EQ(strcmp(testState.record, "AB"), 0);

    // Timer D as 25ms remaining. Timer should be extend to a duration of 75ms
    systemLayer.ExtendTimerTo(75_ms, TestState::D, &testState);
    mockClock.AdvanceMonotonic(100_ms);
    LayerEvents<LayerImpl>::ServiceEvents(systemLayer);
    EXPECT_EQ(strcmp(testState.record, "ABCD"), 0);

    Clock::Internal::SetSystemClockForTesting(savedClock);

    // Extending a timer by 0 ms permitted
    EXPECT_EQ(systemLayer.ExtendTimerTo(0_ms, TestState::A, &testState), CHIP_ERROR_INVALID_ARGUMENT);
}

TEST_F(TestSystemTimer, IsTimerActiveTest)
{
    if (!LayerEvents<LayerImpl>::HasServiceEvents())
        return;

    Layer & systemLayer = mLayer;

    struct TestState
    {
        void Record(char c)
        {
            size_t n = strlen(record);
            if (n + 1 < sizeof(record))
            {
                record[n++] = c;
                record[n]   = 0;
            }
        }
        static void A(Layer * layer, void * state) { static_cast<TestState *>(state)->Record('A'); }
        static void B(Layer * layer, void * state) { static_cast<TestState *>(state)->Record('B'); }
        static void C(Layer * layer, void * state) { static_cast<TestState *>(state)->Record('C'); }
        char record[4] = { 0 };
    };
    TestState testState;
    EXPECT_EQ(testState.record[0], 0);

    Clock::ClockBase * const savedClock = &SystemClock();
    Clock::Internal::MockClock mockClock;
    Clock::Internal::SetSystemClockForTesting(&mockClock);

    using namespace Clock::Literals;
    systemLayer.StartTimer(100_ms, TestState::A, &testState);
    systemLayer.StartTimer(200_ms, TestState::B, &testState);
    systemLayer.StartTimer(300_ms, TestState::C, &testState);

    EXPECT_TRUE(systemLayer.IsTimerActive(TestState::A, &testState));
    EXPECT_TRUE(systemLayer.IsTimerActive(TestState::B, &testState));
    EXPECT_TRUE(systemLayer.IsTimerActive(TestState::C, &testState));

    mockClock.AdvanceMonotonic(100_ms);
    LayerEvents<LayerImpl>::ServiceEvents(systemLayer);
    EXPECT_FALSE(systemLayer.IsTimerActive(TestState::A, &testState));
    EXPECT_TRUE(systemLayer.IsTimerActive(TestState::B, &testState));
    EXPECT_TRUE(systemLayer.IsTimerActive(TestState::C, &testState));

    mockClock.AdvanceMonotonic(100_ms);
    LayerEvents<LayerImpl>::ServiceEvents(systemLayer);
    EXPECT_FALSE(systemLayer.IsTimerActive(TestState::B, &testState));
    EXPECT_TRUE(systemLayer.IsTimerActive(TestState::C, &testState));

    mockClock.AdvanceMonotonic(100_ms);
    LayerEvents<LayerImpl>::ServiceEvents(systemLayer);
    EXPECT_FALSE(systemLayer.IsTimerActive(TestState::C, &testState));

    Clock::Internal::SetSystemClockForTesting(savedClock);
}

} // namespace System
} // namespace chip
