/*
 *
 *    Copyright (c) 2022 Project CHIP Authors
 *    All rights reserved.
 *
 *    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.
 */

#include "AppTask.h"
#include "AppConfig.h"
#include "BoardUtil.h"
#include "LEDUtil.h"
#include "LightSwitch.h"

#include <DeviceInfoProviderImpl.h>
#include <app/clusters/identify-server/identify-server.h>
#include <app/clusters/ota-requestor/OTATestEventTriggerDelegate.h>
#include <app/server/OnboardingCodesUtil.h>
#include <app/server/Server.h>
#include <credentials/DeviceAttestationCredsProvider.h>
#include <credentials/examples/DeviceAttestationCredsExample.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/SafeInt.h>
#include <platform/CHIPDeviceLayer.h>
#include <system/SystemError.h>

#ifdef CONFIG_CHIP_WIFI
#include <app/clusters/network-commissioning/network-commissioning.h>
#include <platform/nrfconnect/wifi/NrfWiFiDriver.h>
#endif

#ifdef CONFIG_CHIP_OTA_REQUESTOR
#include "OTAUtil.h"
#endif

#ifdef CONFIG_CHIP_ICD_SUBSCRIPTION_HANDLING
#include <app/InteractionModelEngine.h>
#endif

#include <dk_buttons_and_leds.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>

LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL);

using namespace ::chip;
using namespace ::chip::app;
using namespace ::chip::Credentials;
using namespace ::chip::DeviceLayer;

namespace {
constexpr EndpointId kLightDimmerSwitchEndpointId  = 1;
constexpr EndpointId kLightGenericSwitchEndpointId = 2;
constexpr EndpointId kLightEndpointId              = 1;

constexpr uint32_t kFactoryResetTriggerTimeout      = 3000;
constexpr uint32_t kFactoryResetCancelWindowTimeout = 3000;
constexpr uint32_t kDimmerTriggeredTimeout          = 500;
constexpr uint32_t kDimmerInterval                  = 300;
constexpr size_t kAppEventQueueSize                 = 10;

K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent));

Identify sIdentify = { kLightEndpointId, AppTask::IdentifyStartHandler, AppTask::IdentifyStopHandler,
                       EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED };

// NOTE! This key is for test/certification only and should not be available in production devices!
// If CONFIG_CHIP_FACTORY_DATA is enabled, this value is read from the factory data.
uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
                                                                                   0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };

LEDWidget sStatusLED;
LEDWidget sIdentifyLED;
#if NUMBER_OF_LEDS == 4
FactoryResetLEDsWrapper<2> sFactoryResetLEDs{ { FACTORY_RESET_SIGNAL_LED, FACTORY_RESET_SIGNAL_LED1 } };
#endif

bool sIsNetworkProvisioned = false;
bool sIsNetworkEnabled     = false;
bool sHaveBLEConnections   = false;
bool sWasDimmerTriggered   = false;

k_timer sFunctionTimer;
k_timer sDimmerPressKeyTimer;
k_timer sDimmerTimer;

chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider;
} // namespace

namespace LedConsts {
constexpr uint32_t kBlinkRate_ms{ 500 };
constexpr uint32_t kIdentifyBlinkRate_ms{ 500 };

namespace StatusLed {
namespace Unprovisioned {
constexpr uint32_t kOn_ms{ 100 };
constexpr uint32_t kOff_ms{ kOn_ms };
} // namespace Unprovisioned
namespace Provisioned {
constexpr uint32_t kOn_ms{ 50 };
constexpr uint32_t kOff_ms{ 950 };
} // namespace Provisioned

} // namespace StatusLed
} // namespace LedConsts

#ifdef CONFIG_CHIP_WIFI
app::Clusters::NetworkCommissioning::Instance sWiFiCommissioningInstance(0, &(NetworkCommissioning::NrfWiFiDriver::Instance()));
#endif

CHIP_ERROR AppTask::Init()
{
    // Initialize CHIP
    LOG_INF("Init CHIP stack");

    CHIP_ERROR err = Platform::MemoryInit();
    if (err != CHIP_NO_ERROR)
    {
        LOG_ERR("Platform::MemoryInit() failed");
        return err;
    }

    err = PlatformMgr().InitChipStack();
    if (err != CHIP_NO_ERROR)
    {
        LOG_ERR("PlatformMgr().InitChipStack() failed");
        return err;
    }

#if defined(CONFIG_NET_L2_OPENTHREAD)
    err = ThreadStackMgr().InitThreadStack();
    if (err != CHIP_NO_ERROR)
    {
        LOG_ERR("ThreadStackMgr().InitThreadStack() failed: %s", ErrorStr(err));
        return err;
    }

#ifdef CONFIG_OPENTHREAD_MTD_SED
    err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice);
#else
    err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice);
#endif
    if (err != CHIP_NO_ERROR)
    {
        LOG_ERR("ConnectivityMgr().SetThreadDeviceType() failed: %s", ErrorStr(err));
        return err;
    }
#elif defined(CONFIG_CHIP_WIFI)
    sWiFiCommissioningInstance.Init();
#else
    return CHIP_ERROR_INTERNAL;
#endif

    LightSwitch::GetInstance().Init(kLightDimmerSwitchEndpointId, kLightGenericSwitchEndpointId);

    // Initialize UI components
    LEDWidget::InitGpio();
    LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler);

    sStatusLED.Init(SYSTEM_STATE_LED);
    sIdentifyLED.Init(IDENTIFY_LED);
    UpdateStatusLED();

    int ret = dk_buttons_init(ButtonEventHandler);
    if (ret)
    {
        LOG_ERR("dk_buttons_init() failed");
        return System::MapErrorZephyr(ret);
    }

    // Initialize Timers
    k_timer_init(&sFunctionTimer, AppTask::FunctionTimerTimeoutCallback, nullptr);
    k_timer_init(&sDimmerPressKeyTimer, AppTask::FunctionTimerTimeoutCallback, nullptr);
    k_timer_init(&sDimmerTimer, AppTask::FunctionTimerTimeoutCallback, nullptr);
    k_timer_user_data_set(&sDimmerTimer, this);
    k_timer_user_data_set(&sDimmerPressKeyTimer, this);
    k_timer_user_data_set(&sFunctionTimer, this);

    // Initialize DFU
#ifdef CONFIG_MCUMGR_SMP_BT
    GetDFUOverSMP().Init();
    GetDFUOverSMP().ConfirmNewImage();
#endif

    // Print initial configs
#if CONFIG_CHIP_FACTORY_DATA
    ReturnErrorOnFailure(mFactoryDataProvider.Init());
    SetDeviceInstanceInfoProvider(&mFactoryDataProvider);
    SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider);
    SetCommissionableDataProvider(&mFactoryDataProvider);
    // Read EnableKey from the factory data.
    MutableByteSpan enableKey(sTestEventTriggerEnableKey);
    err = mFactoryDataProvider.GetEnableKey(enableKey);
    if (err != CHIP_NO_ERROR)
    {
        LOG_ERR("mFactoryDataProvider.GetEnableKey() failed. Could not delegate a test event trigger");
        memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey));
    }
#else
    SetDeviceInstanceInfoProvider(&DeviceInstanceInfoProviderMgrImpl());
    SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());
#endif

    static CommonCaseDeviceServerInitParams initParams;
    static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) };
    (void) initParams.InitializeStaticResourcesBeforeServerInit();
    initParams.testEventTriggerDelegate = &testEventTriggerDelegate;
    ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams));

    gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage());
    chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider);

    ConfigurationMgr().LogDeviceConfig();
    PrintOnboardingCodes(RendezvousInformationFlags(RendezvousInformationFlag::kBLE));

#ifdef CONFIG_CHIP_ICD_SUBSCRIPTION_HANDLING
    chip::app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(&GetICDUtil());
#endif

    // Add CHIP event handler and start CHIP thread.
    // Note that all the initialization code should happen prior to this point
    // to avoid data races between the main and the CHIP threads.
    PlatformMgr().AddEventHandler(ChipEventHandler, 0);

    err = PlatformMgr().StartEventLoopTask();
    if (err != CHIP_NO_ERROR)
    {
        LOG_ERR("PlatformMgr().StartEventLoopTask() failed");
        return err;
    }

    return err;
}

CHIP_ERROR AppTask::StartApp()
{
    ReturnErrorOnFailure(Init());

    AppEvent event{};

    while (true)
    {
        k_msgq_get(&sAppEventQueue, &event, K_FOREVER);
        DispatchEvent(event);
    }

    return CHIP_NO_ERROR;
}

void AppTask::ButtonPushHandler(const AppEvent & event)
{
    if (event.Type == AppEventType::Button)
    {
        switch (event.ButtonEvent.PinNo)
        {
        case FUNCTION_BUTTON:
            Instance().StartTimer(Timer::Function, kFactoryResetTriggerTimeout);
            Instance().mFunction = FunctionEvent::SoftwareUpdate;
            break;
        case
#if NUMBER_OF_BUTTONS == 2
            BLE_ADVERTISEMENT_START_AND_SWITCH_BUTTON:
            if (!ConnectivityMgr().IsBLEAdvertisingEnabled() && Server::GetInstance().GetFabricTable().FabricCount() == 0)
            {
                break;
            }
#else
            SWITCH_BUTTON:
#endif
            LOG_INF("Button has been pressed, keep in this state for at least 500 ms to change light sensitivity of binded "
                    "lighting devices.");
            Instance().StartTimer(Timer::DimmerTrigger, kDimmerTriggeredTimeout);
            break;
        default:
            break;
        }
    }
}

void AppTask::ButtonReleaseHandler(const AppEvent & event)
{
    if (event.Type == AppEventType::Button)
    {
        switch (event.ButtonEvent.PinNo)
        {
        case FUNCTION_BUTTON:
            if (Instance().mFunction == FunctionEvent::SoftwareUpdate)
            {
                Instance().CancelTimer(Timer::Function);
                Instance().mFunction = FunctionEvent::NoneSelected;

#ifdef CONFIG_MCUMGR_SMP_BT
                GetDFUOverSMP().StartServer();
                UpdateStatusLED();
#else
                LOG_INF("Software update is disabled");
#endif
            }
            else if (Instance().mFunction == FunctionEvent::FactoryReset)
            {
                UpdateStatusLED();

                Instance().CancelTimer(Timer::Function);
                Instance().mFunction = FunctionEvent::NoneSelected;
                LOG_INF("Factory Reset has been canceled");
            }
            break;
#if NUMBER_OF_BUTTONS == 4
        case SWITCH_BUTTON:
#else
        case BLE_ADVERTISEMENT_START_AND_SWITCH_BUTTON:
            if (!ConnectivityMgr().IsBLEAdvertisingEnabled() && Server::GetInstance().GetFabricTable().FabricCount() == 0)
            {
                AppEvent buttonEvent;
                buttonEvent.Type               = AppEventType::Button;
                buttonEvent.ButtonEvent.PinNo  = BLE_ADVERTISEMENT_START_AND_SWITCH_BUTTON;
                buttonEvent.ButtonEvent.Action = static_cast<uint8_t>(AppEventType::ButtonPushed);
                buttonEvent.Handler            = StartBLEAdvertisementHandler;
                PostEvent(buttonEvent);
                break;
            }
#endif
            if (!sWasDimmerTriggered)
            {
                LightSwitch::GetInstance().InitiateActionSwitch(LightSwitch::Action::Toggle);
            }
            Instance().CancelTimer(Timer::Dimmer);
            Instance().CancelTimer(Timer::DimmerTrigger);
            sWasDimmerTriggered = false;
            break;
        default:
            break;
        }
    }
}

void AppTask::TimerEventHandler(const AppEvent & event)
{
    if (event.Type == AppEventType::Timer)
    {
        switch (static_cast<Timer>(event.TimerEvent.TimerType))
        {
        case Timer::Function:
            if (Instance().mFunction == FunctionEvent::SoftwareUpdate)
            {
                LOG_INF("Factory Reset has been triggered. Release button within %u ms to cancel.",
                        kFactoryResetCancelWindowTimeout);
                Instance().StartTimer(Timer::Function, kFactoryResetCancelWindowTimeout);
                Instance().mFunction = FunctionEvent::FactoryReset;

#ifdef CONFIG_STATE_LEDS
                // reset all LEDs to synchronize factory reset blinking
                sStatusLED.Set(false);
                sIdentifyLED.Set(false);
#if NUMBER_OF_LEDS == 4
                sFactoryResetLEDs.Set(false);
#endif

                sStatusLED.Blink(LedConsts::kBlinkRate_ms);
                sIdentifyLED.Blink(LedConsts::kBlinkRate_ms);
#if NUMBER_OF_LEDS == 4
                sFactoryResetLEDs.Blink(LedConsts::kBlinkRate_ms);
#endif
#endif
            }
            else if (Instance().mFunction == FunctionEvent::FactoryReset)
            {
                Instance().mFunction = FunctionEvent::NoneSelected;
                LOG_INF("Factory Reset triggered");
                chip::Server::GetInstance().ScheduleFactoryReset();
            }
            break;
        case Timer::DimmerTrigger:
            LOG_INF("Dimming started...");
            sWasDimmerTriggered = true;
            LightSwitch::GetInstance().InitiateActionSwitch(LightSwitch::Action::On);
            Instance().StartTimer(Timer::Dimmer, kDimmerInterval);
            Instance().CancelTimer(Timer::DimmerTrigger);
            break;
        case Timer::Dimmer:
            LightSwitch::GetInstance().DimmerChangeBrightness();
            break;
        default:
            break;
        }
    }
}

void AppTask::IdentifyStartHandler(Identify *)
{
    AppEvent event;
    event.Type    = AppEventType::IdentifyStart;
    event.Handler = [](const AppEvent &) { sIdentifyLED.Blink(LedConsts::kIdentifyBlinkRate_ms); };
    PostEvent(event);
}

void AppTask::IdentifyStopHandler(Identify *)
{
    AppEvent event;
    event.Type    = AppEventType::IdentifyStop;
    event.Handler = [](const AppEvent &) { sIdentifyLED.Set(false); };
    PostEvent(event);
}

void AppTask::StartBLEAdvertisementHandler(const AppEvent &)
{
    if (Server::GetInstance().GetFabricTable().FabricCount() != 0)
    {
        LOG_INF("Matter service BLE advertising not started - device is already commissioned");
        return;
    }

    if (ConnectivityMgr().IsBLEAdvertisingEnabled())
    {
        LOG_INF("BLE advertising is already enabled");
        return;
    }

    if (Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() != CHIP_NO_ERROR)
    {
        LOG_ERR("OpenBasicCommissioningWindow() failed");
    }
}

void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */)
{
    switch (event->Type)
    {
    case DeviceEventType::kCHIPoBLEAdvertisingChange:
        UpdateStatusLED();
#ifdef CONFIG_CHIP_NFC_COMMISSIONING
        if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Started)
        {
            if (NFCMgr().IsTagEmulationStarted())
            {
                LOG_INF("NFC Tag emulation is already started");
            }
            else
            {
                ShareQRCodeOverNFC(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE));
            }
        }
        else if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Stopped)
        {
            NFCMgr().StopTagEmulation();
        }
#endif
        sHaveBLEConnections = ConnectivityMgr().NumBLEConnections() != 0;
        UpdateStatusLED();
        break;
#if defined(CONFIG_NET_L2_OPENTHREAD)
    case DeviceEventType::kDnssdInitialized:
#if CONFIG_CHIP_OTA_REQUESTOR
        InitBasicOTARequestor();
#endif // CONFIG_CHIP_OTA_REQUESTOR
        break;
    case DeviceEventType::kThreadStateChange:
        sIsNetworkProvisioned = ConnectivityMgr().IsThreadProvisioned();
        sIsNetworkEnabled     = ConnectivityMgr().IsThreadEnabled();
#elif defined(CONFIG_CHIP_WIFI)
    case DeviceEventType::kWiFiConnectivityChange:
        sIsNetworkProvisioned = ConnectivityMgr().IsWiFiStationProvisioned();
        sIsNetworkEnabled     = ConnectivityMgr().IsWiFiStationEnabled();
#if CONFIG_CHIP_OTA_REQUESTOR
        if (event->WiFiConnectivityChange.Result == kConnectivity_Established)
        {
            InitBasicOTARequestor();
        }
#endif // CONFIG_CHIP_OTA_REQUESTOR
#endif
        UpdateStatusLED();
        break;
    default:
        break;
    }
}

void AppTask::UpdateStatusLED()
{
#ifdef CONFIG_STATE_LEDS
#if NUMBER_OF_LEDS == 4
    sFactoryResetLEDs.Set(false);
#endif

    // Update the status LED.
    //
    // If IPv6 network and service provisioned, keep the LED on constantly.
    //
    // If the system has BLE connection(s) up till the stage above, THEN blink the LED at an even
    // rate of 100ms.
    //
    // Otherwise, blink the LED for a very short time.
    if (sIsNetworkProvisioned && sIsNetworkEnabled)
    {
        sStatusLED.Set(true);
    }
    else if (sHaveBLEConnections)
    {
        sStatusLED.Blink(LedConsts::StatusLed::Unprovisioned::kOn_ms, LedConsts::StatusLed::Unprovisioned::kOff_ms);
    }
    else
    {
        sStatusLED.Blink(LedConsts::StatusLed::Provisioned::kOn_ms, LedConsts::StatusLed::Provisioned::kOff_ms);
    }
#endif
}

void AppTask::ButtonEventHandler(uint32_t buttonState, uint32_t hasChanged)
{
    AppEvent buttonEvent;
    buttonEvent.Type = AppEventType::Button;

    if (FUNCTION_BUTTON_MASK & buttonState & hasChanged)
    {
        buttonEvent.ButtonEvent.PinNo  = FUNCTION_BUTTON;
        buttonEvent.ButtonEvent.Action = static_cast<uint8_t>(AppEventType::ButtonPushed);
        buttonEvent.Handler            = ButtonPushHandler;
        PostEvent(buttonEvent);
    }
    else if (FUNCTION_BUTTON_MASK & hasChanged)
    {
        buttonEvent.ButtonEvent.PinNo  = FUNCTION_BUTTON;
        buttonEvent.ButtonEvent.Action = static_cast<uint8_t>(AppEventType::ButtonReleased);
        buttonEvent.Handler            = ButtonReleaseHandler;
        PostEvent(buttonEvent);
    }

#if NUMBER_OF_BUTTONS == 2
    uint32_t buttonMask           = BLE_ADVERTISEMENT_START_AND_SWITCH_BUTTON_MASK;
    buttonEvent.ButtonEvent.PinNo = BLE_ADVERTISEMENT_START_AND_SWITCH_BUTTON;
#else
    uint32_t buttonMask           = SWITCH_BUTTON_MASK;
    buttonEvent.ButtonEvent.PinNo = SWITCH_BUTTON;
#endif

    if (buttonMask & buttonState & hasChanged)
    {
        buttonEvent.ButtonEvent.Action = static_cast<uint8_t>(AppEventType::ButtonPushed);
        buttonEvent.Handler            = ButtonPushHandler;
        PostEvent(buttonEvent);
    }
    else if (buttonMask & hasChanged)
    {
        buttonEvent.ButtonEvent.Action = static_cast<uint8_t>(AppEventType::ButtonReleased);
        buttonEvent.Handler            = ButtonReleaseHandler;
        PostEvent(buttonEvent);
    }

#if NUMBER_OF_BUTTONS == 4
    if (BLE_ADVERTISEMENT_START_BUTTON_MASK & hasChanged & buttonState)
    {
        buttonEvent.ButtonEvent.PinNo  = BLE_ADVERTISEMENT_START_BUTTON;
        buttonEvent.ButtonEvent.Action = static_cast<uint8_t>(AppEventType::ButtonPushed);
        buttonEvent.Handler            = StartBLEAdvertisementHandler;
        PostEvent(buttonEvent);
    }
#endif
}

void AppTask::StartTimer(Timer timer, uint32_t timeoutMs)
{
    switch (timer)
    {
    case Timer::Function:
        k_timer_start(&sFunctionTimer, K_MSEC(timeoutMs), K_NO_WAIT);
        break;
    case Timer::DimmerTrigger:
        k_timer_start(&sDimmerPressKeyTimer, K_MSEC(timeoutMs), K_NO_WAIT);
        break;
    case Timer::Dimmer:
        k_timer_start(&sDimmerTimer, K_MSEC(timeoutMs), K_MSEC(timeoutMs));
        break;
    default:
        break;
    }
}

void AppTask::CancelTimer(Timer timer)
{
    switch (timer)
    {
    case Timer::Function:
        k_timer_stop(&sFunctionTimer);
        break;
    case Timer::DimmerTrigger:
        k_timer_stop(&sDimmerPressKeyTimer);
        break;
    case Timer::Dimmer:
        k_timer_stop(&sDimmerTimer);
        break;
    default:
        break;
    }
}

void AppTask::UpdateLedStateEventHandler(const AppEvent & event)
{
    if (event.Type == AppEventType::UpdateLedState)
    {
        event.UpdateLedStateEvent.LedWidget->UpdateState();
    }
}

void AppTask::LEDStateUpdateHandler(LEDWidget & aLedWidget)
{
    AppEvent event;
    event.Type                          = AppEventType::UpdateLedState;
    event.Handler                       = UpdateLedStateEventHandler;
    event.UpdateLedStateEvent.LedWidget = &aLedWidget;
    PostEvent(event);
}

void AppTask::FunctionTimerTimeoutCallback(k_timer * timer)
{
    if (!timer)
    {
        return;
    }

    AppEvent event;
    if (timer == &sFunctionTimer)
    {
        event.Type                 = AppEventType::Timer;
        event.TimerEvent.TimerType = (uint8_t) Timer::Function;
        event.TimerEvent.Context   = k_timer_user_data_get(timer);
        event.Handler              = TimerEventHandler;
        PostEvent(event);
    }
    if (timer == &sDimmerPressKeyTimer)
    {
        event.Type                 = AppEventType::Timer;
        event.TimerEvent.TimerType = (uint8_t) Timer::DimmerTrigger;
        event.TimerEvent.Context   = k_timer_user_data_get(timer);
        event.Handler              = TimerEventHandler;
        PostEvent(event);
    }
    if (timer == &sDimmerTimer)
    {
        event.Type                 = AppEventType::Timer;
        event.TimerEvent.TimerType = (uint8_t) Timer::Dimmer;
        event.TimerEvent.Context   = k_timer_user_data_get(timer);
        event.Handler              = TimerEventHandler;
        PostEvent(event);
    }
}

void AppTask::PostEvent(const AppEvent & event)
{
    if (k_msgq_put(&sAppEventQueue, &event, K_NO_WAIT) != 0)
    {
        LOG_INF("Failed to post event to app task event queue");
    }
}

void AppTask::DispatchEvent(const AppEvent & event)
{
    if (event.Handler)
    {
        event.Handler(event);
    }
    else
    {
        LOG_INF("Event received with no handler. Dropping event.");
    }
}
