/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *    Copyright (c) 2019 Google LLC.
 *    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 <LEDWidget.h>
#include <plat.h>

#include <app-common/zap-generated/attribute-id.h>
#include <app-common/zap-generated/attribute-type.h>
#include <app-common/zap-generated/attributes/Accessors.h>
#include <app-common/zap-generated/ids/Clusters.h>
#include <app/clusters/identify-server/identify-server.h>
#include <app/util/attribute-storage.h>

#include <app/server/Dnssd.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/ErrorStr.h>
#include <system/SystemClock.h>
#ifdef OTA_ENABLED
#include "OTAConfig.h"
#endif // OTA_ENABLED

#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
#include <NetworkCommissioningDriver.h>
#include <route_hook/bl_route_hook.h>
#endif

#if HEAP_MONITORING
#include "MemMonitoring.h"
#endif

#if CHIP_ENABLE_OPENTHREAD
#include <ThreadStackManagerImpl.h>
#include <platform/OpenThread/OpenThreadUtils.h>
#include <platform/ThreadStackManager.h>
#include <utils_list.h>
#endif

#if CONFIG_ENABLE_CHIP_SHELL
#include <ChipShellCollection.h>
#include <lib/shell/Engine.h>
#endif

extern "C" {
#include "board.h"
#include <bl_gpio.h>
#include <easyflash.h>
#include <hal_gpio.h>
#include <hosal_gpio.h>
}

#include "AppTask.h"

namespace {

#if defined(BL706_NIGHT_LIGHT) || defined(BL602_NIGHT_LIGHT)
ColorLEDWidget sLightLED;
#else
DimmableLEDWidget sLightLED;
#endif

Identify sIdentify = {
    APP_LIGHT_ENDPOINT_ID,
    AppTask::IdentifyStartHandler,
    AppTask::IdentifyStopHandler,
    EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LIGHT,
};

} // namespace

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

#if CONFIG_ENABLE_CHIP_SHELL
using namespace chip::Shell;
#endif

AppTask AppTask::sAppTask;
StackType_t AppTask::appStack[APP_TASK_STACK_SIZE / sizeof(StackType_t)];
StaticTask_t AppTask::appTaskStruct;

void StartAppTask(void)
{
    GetAppTask().sAppTaskHandle = xTaskCreateStatic(GetAppTask().AppTaskMain, APP_TASK_NAME, ArraySize(GetAppTask().appStack), NULL,
                                                    APP_TASK_PRIORITY, GetAppTask().appStack, &GetAppTask().appTaskStruct);
    if (GetAppTask().sAppTaskHandle == NULL)
    {
        ChipLogError(NotSpecified, "Failed to create app task");
        appError(APP_ERROR_EVENT_QUEUE_FAILED);
    }
}

#if CONFIG_ENABLE_CHIP_SHELL
void AppTask::AppShellTask(void * args)
{
    Engine::Root().RunMainLoop();
}

CHIP_ERROR AppTask::StartAppShellTask()
{
    static TaskHandle_t shellTask;

    Engine::Root().Init();

    cmd_misc_init();

    xTaskCreate(AppTask::AppShellTask, "chip_shell", 1024 / sizeof(configSTACK_DEPTH_TYPE), NULL, APP_TASK_PRIORITY, &shellTask);

    return CHIP_NO_ERROR;
}
#endif

void AppTask::PostEvent(app_event_t event)
{
    if (xPortIsInsideInterrupt())
    {
        BaseType_t higherPrioTaskWoken = pdFALSE;
        xTaskNotifyFromISR(sAppTaskHandle, event, eSetBits, &higherPrioTaskWoken);
    }
    else
    {
        xTaskNotify(sAppTaskHandle, event, eSetBits);
    }
}

void AppTask::AppTaskMain(void * pvParameter)
{
    app_event_t appEvent;
    bool isStateReady = false;

    sLightLED.Init();

#ifdef LED_BTN_RESET
    ButtonInit();
#else

    uint32_t resetCnt      = 0;
    size_t saved_value_len = 0;
    ef_get_env_blob(APP_REBOOT_RESET_COUNT_KEY, &resetCnt, sizeof(resetCnt), &saved_value_len);
    resetCnt++;
    ef_set_env_blob(APP_REBOOT_RESET_COUNT_KEY, &resetCnt, sizeof(resetCnt));
#endif

    ChipLogProgress(NotSpecified, "Starting Platform Manager Event Loop");
    CHIP_ERROR ret = PlatformMgr().StartEventLoopTask();
    if (ret != CHIP_NO_ERROR)
    {
        ChipLogError(NotSpecified, "PlatformMgr().StartEventLoopTask() failed");
        appError(ret);
    }

    GetAppTask().PostEvent(AppTask::APP_EVENT_TIMER);
    vTaskSuspend(NULL);

#ifndef LED_BTN_RESET
    GetAppTask().mButtonPressedTime = chip::System::SystemClock().GetMonotonicMilliseconds64().count() + 1;
    if (ConnectivityMgr().IsThreadProvisioned())
    {
        GetAppTask().PostEvent(APP_EVENT_SYS_PROVISIONED);
    }
#endif

    GetAppTask().mIsConnected = false;

    GetAppTask().sTimer = xTimerCreate("lightTmr", pdMS_TO_TICKS(1000), false, NULL, AppTask::TimerCallback);
    if (GetAppTask().sTimer == NULL)
    {
        ChipLogError(NotSpecified, "Failed to create timer task");
        appError(APP_ERROR_EVENT_QUEUE_FAILED);
    }

    ChipLogProgress(NotSpecified, "App Task started, with heap %d left\r\n", xPortGetFreeHeapSize());

    StartTimer();

    while (true)
    {
        appEvent                 = APP_EVENT_NONE;
        BaseType_t eventReceived = xTaskNotifyWait(0, APP_EVENT_ALL_MASK, (uint32_t *) &appEvent, portMAX_DELAY);

        if (eventReceived)
        {
            PlatformMgr().LockChipStack();
            if (APP_EVENT_SYS_BLE_ADV & appEvent)
            {
                LightingSetStatus(APP_EVENT_SYS_BLE_ADV);
                LightingUpdate(APP_EVENT_LIGHTING_GO_THROUGH);

                isStateReady = false;
            }

            if (APP_EVENT_SYS_PROVISIONED & appEvent)
            {
                LightingSetStatus(APP_EVENT_SYS_PROVISIONED);
                LightingUpdate(APP_EVENT_LIGHTING_GO_THROUGH);

                isStateReady = true;
            }

            if (APP_EVENT_BTN_SHORT & appEvent)
            {
                LightingSetStatus(APP_EVENT_SYS_LIGHT_TOGGLE);
                LightingUpdate(APP_EVENT_LIGHTING_GO_THROUGH);
            }

            if ((APP_EVENT_LIGHTING_MASK & appEvent) && isStateReady)
            {
                LightingUpdate((app_event_t)(APP_EVENT_LIGHTING_MASK & appEvent));
            }

            if (APP_EVENT_IDENTIFY_MASK & appEvent)
            {
                IdentifyHandleOp(appEvent);
            }

            if (APP_EVENT_FACTORY_RESET & appEvent)
            {
                DeviceLayer::ConfigurationMgr().InitiateFactoryReset();
            }

            TimerEventHandler(appEvent);

            PlatformMgr().UnlockChipStack();
        }
    }
}

void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t arg)
{
    switch (event->Type)
    {
    case DeviceEventType::kCHIPoBLEAdvertisingChange:

#ifndef LED_BTN_RESET
        if (ConnectivityMgr().IsThreadProvisioned())
        {
            GetAppTask().PostEvent(APP_EVENT_SYS_PROVISIONED);
            break;
        }
#endif

        if (ConnectivityMgr().NumBLEConnections())
        {
            GetAppTask().PostEvent(APP_EVENT_SYS_BLE_CONN);
        }
        else
        {
            GetAppTask().PostEvent(APP_EVENT_SYS_BLE_ADV);

#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
            GetAppTask().mIsConnected = ConnectivityMgr().IsWiFiStationConnected();
#endif
#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
            GetAppTask().mIsConnected = ConnectivityMgr().IsThreadAttached();
#endif
        }
        ChipLogProgress(NotSpecified, "BLE adv changed, connection number: %d\r\n", ConnectivityMgr().NumBLEConnections());
        break;
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
    case DeviceEventType::kThreadStateChange:

        ChipLogProgress(NotSpecified, "Thread state changed, IsThreadAttached: %d\r\n", ConnectivityMgr().IsThreadAttached());
        if (!GetAppTask().mIsConnected && ConnectivityMgr().IsThreadAttached())
        {
            GetAppTask().PostEvent(APP_EVENT_SYS_PROVISIONED);
            GetAppTask().mIsConnected = true;
        }
        break;
#endif

#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
    case DeviceEventType::kWiFiConnectivityChange:

        ChipLogProgress(NotSpecified, "Wi-Fi state changed to %s.\r\n",
                        ConnectivityMgr().IsWiFiStationConnected() ? "connected" : "disconnected");

        chip::app::DnssdServer::Instance().StartServer();
        NetworkCommissioning::BLWiFiDriver::GetInstance().SaveConfiguration();
        if (!GetAppTask().mIsConnected && ConnectivityMgr().IsWiFiStationConnected())
        {
            GetAppTask().PostEvent(APP_EVENT_SYS_PROVISIONED);
            GetAppTask().mIsConnected = true;
        }
        break;

    case DeviceEventType::kInterfaceIpAddressChanged:
        if ((event->InterfaceIpAddressChanged.Type == InterfaceIpChangeType::kIpV4_Assigned) ||
            (event->InterfaceIpAddressChanged.Type == InterfaceIpChangeType::kIpV6_Assigned))
        {
            // MDNS server restart on any ip assignment: if link local ipv6 is configured, that
            // will not trigger a 'internet connectivity change' as there is no internet
            // connectivity. MDNS still wants to refresh its listening interfaces to include the
            // newly selected address.
            chip::app::DnssdServer::Instance().StartServer();
        }

        if (event->InterfaceIpAddressChanged.Type == InterfaceIpChangeType::kIpV6_Assigned)
        {
            ChipLogProgress(NotSpecified, "Initializing route hook...");
            bl_route_hook_init();
        }
        break;
#endif
    case DeviceEventType::kFailSafeTimerExpired:

#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
        GetAppTask().mIsConnected = ConnectivityMgr().IsWiFiStationConnected();
#endif
#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
        GetAppTask().mIsConnected = ConnectivityMgr().IsThreadAttached();
#endif

        break;
    default:
        break;
    }
}

void AppTask::LightingUpdate(app_event_t event)
{
    uint8_t v, onoff, hue, sat;
    EndpointId endpoint = GetAppTask().GetEndpointId();

    do
    {
        if (EMBER_ZCL_STATUS_SUCCESS !=
            emberAfReadAttribute(endpoint, Clusters::OnOff::Id, ZCL_ON_OFF_ATTRIBUTE_ID, &onoff, sizeof(onoff)))
        {
            break;
        }

        if (EMBER_ZCL_STATUS_SUCCESS !=
            emberAfReadAttribute(endpoint, Clusters::LevelControl::Id, ZCL_CURRENT_LEVEL_ATTRIBUTE_ID, &v, sizeof(v)))
        {
            break;
        }

        if (EMBER_ZCL_STATUS_SUCCESS !=
            emberAfReadAttribute(endpoint, Clusters::ColorControl::Id, ZCL_COLOR_CONTROL_CURRENT_HUE_ATTRIBUTE_ID, &hue, sizeof(v)))
        {
            break;
        }

        if (EMBER_ZCL_STATUS_SUCCESS !=
            emberAfReadAttribute(endpoint, Clusters::ColorControl::Id, ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID, &sat,
                                 sizeof(v)))
        {
            break;
        }

        if (0 == onoff)
        {
            sLightLED.SetLevel(0);
        }
        else
        {
#if defined(BL706_NIGHT_LIGHT) || defined(BL602_NIGHT_LIGHT)
            sLightLED.SetColor(v, hue, sat);
#else
            sLightLED.SetLevel(v);
#endif
        }

    } while (0);
}

void AppTask::LightingSetOnoff(uint8_t bonoff)
{
    uint8_t newValue    = bonoff;
    EndpointId endpoint = GetAppTask().GetEndpointId();

    // write the new on/off value
    emberAfWriteAttribute(endpoint, Clusters::OnOff::Id, ZCL_ON_OFF_ATTRIBUTE_ID, (uint8_t *) &newValue,
                          ZCL_BOOLEAN_ATTRIBUTE_TYPE);
    newValue = 254;
    emberAfWriteAttribute(endpoint, Clusters::LevelControl::Id, ZCL_CURRENT_LEVEL_ATTRIBUTE_ID, (uint8_t *) &newValue,
                          ZCL_INT8U_ATTRIBUTE_TYPE);
}

void AppTask::LightingSetStatus(app_event_t status)
{
    uint8_t onoff             = 1, level, hue, sat;
    EndpointId endpoint       = GetAppTask().GetEndpointId();
    static bool isProvisioned = false;

    if (APP_EVENT_SYS_LIGHT_TOGGLE == status)
    {
        emberAfReadAttribute(endpoint, Clusters::OnOff::Id, ZCL_ON_OFF_ATTRIBUTE_ID, (uint8_t *) &onoff,
                             ZCL_BOOLEAN_ATTRIBUTE_TYPE);
        onoff = 1 - onoff;
    }
    else if (APP_EVENT_SYS_BLE_ADV == status)
    {
        hue = 35;
        emberAfWriteAttribute(endpoint, Clusters::ColorControl::Id, ZCL_COLOR_CONTROL_CURRENT_HUE_ATTRIBUTE_ID, (uint8_t *) &hue,
                              ZCL_INT8U_ATTRIBUTE_TYPE);
        sat = 254;
        emberAfWriteAttribute(endpoint, Clusters::ColorControl::Id, ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID,
                              (uint8_t *) &sat, ZCL_INT8U_ATTRIBUTE_TYPE);
        level = 254;
        emberAfWriteAttribute(endpoint, Clusters::LevelControl::Id, ZCL_CURRENT_LEVEL_ATTRIBUTE_ID, (uint8_t *) &level,
                              ZCL_INT8U_ATTRIBUTE_TYPE);

        isProvisioned = false;
    }
    else if (APP_EVENT_SYS_PROVISIONED == status)
    {
        if (isProvisioned)
        {
            return;
        }
        isProvisioned = true;
        sat           = 0;
        emberAfWriteAttribute(endpoint, Clusters::ColorControl::Id, ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID,
                              (uint8_t *) &sat, ZCL_INT8U_ATTRIBUTE_TYPE);
        level = 254;
        emberAfWriteAttribute(endpoint, Clusters::LevelControl::Id, ZCL_CURRENT_LEVEL_ATTRIBUTE_ID, (uint8_t *) &level,
                              ZCL_INT8U_ATTRIBUTE_TYPE);
    }

    emberAfWriteAttribute(endpoint, Clusters::OnOff::Id, ZCL_ON_OFF_ATTRIBUTE_ID, (uint8_t *) &onoff, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

bool AppTask::StartTimer(void)
{
    if (xTimerIsTimerActive(GetAppTask().sTimer))
    {
        CancelTimer();
    }

    if (GetAppTask().mTimerIntvl == 0)
    {
        GetAppTask().mTimerIntvl = 1000;
    }

    if (xTimerChangePeriod(GetAppTask().sTimer, pdMS_TO_TICKS(GetAppTask().mTimerIntvl), pdMS_TO_TICKS(100)) != pdPASS)
    {
        ChipLogProgress(NotSpecified, "Failed to access timer with 100 ms delay.");
    }

    return true;
}

void AppTask::CancelTimer(void)
{
    xTimerStop(GetAppTask().sTimer, 0);
}

void AppTask::TimerCallback(TimerHandle_t xTimer)
{
    GetAppTask().PostEvent(APP_EVENT_TIMER);
}

void AppTask::TimerEventHandler(app_event_t event)
{
    if (event & APP_EVENT_BTN_FACTORY_RESET_PRESS)
    {
        GetAppTask().mTimerIntvl = APP_BUTTON_PRESS_JITTER;
        StartTimer();
    }
    else if (event & APP_EVENT_BTN_FACTORY_RESET_IND)
    {
        if (GetAppTask().mButtonPressedTime)
        {
            GetAppTask().mIsFactoryResetIndicat = true;
#if defined(BL706_NIGHT_LIGHT) || defined(BL602_NIGHT_LIGHT)
            sLightLED.SetColor(254, 0, 210);
#ifndef LED_BTN_RESET
            uint32_t resetCnt               = 0;
            GetAppTask().mButtonPressedTime = 0;
            ef_set_env_blob(APP_REBOOT_RESET_COUNT_KEY, &resetCnt, sizeof(resetCnt));

            vTaskDelay(APP_BUTTON_PRESS_LONG);
            GetAppTask().PostEvent(APP_EVENT_FACTORY_RESET);
#endif
#else
            sLightLED.Toggle();
            GetAppTask().mTimerIntvl = 100;
            StartTimer();
#endif
        }
    }

    if (event & APP_EVENT_BTN_FACTORY_RESET_CANCEL)
    {
        GetAppTask().mTimerIntvl = 1000;
        StartTimer();
        if (GetAppTask().mIsFactoryResetIndicat)
        {
            LightingUpdate(APP_EVENT_LIGHTING_GO_THROUGH);
        }
        GetAppTask().mIsFactoryResetIndicat = false;
        GetAppTask().mButtonPressedTime     = 0;
    }

    if (APP_EVENT_TIMER & event)
    {
        if (GetAppTask().mButtonPressedTime)
        {
            if (GetAppTask().mIsFactoryResetIndicat)
            {
                if (chip::System::SystemClock().GetMonotonicMilliseconds64().count() - GetAppTask().mButtonPressedTime >=
                    APP_BUTTON_PRESS_LONG)
                {
                    /** factory reset indicat done. */
                    sLightLED.SetOnoff(false);
                    GetAppTask().mTimerIntvl = 1000;
                }
                else
                {
#if !(defined(BL706_NIGHT_LIGHT) || defined(BL602_NIGHT_LIGHT))
                    sLightLED.Toggle();
#endif
                }
            }
            else
            {

#ifdef BL706_NIGHT_LIGHT

                if (GetAppTask().mButtonPressedTime)
                {
                    uint32_t resetCnt = 0;

                    if (chip::System::SystemClock().GetMonotonicMilliseconds64().count() - GetAppTask().mButtonPressedTime >
                        APP_BUTTON_PRESS_LONG * 2)
                    {
                        GetAppTask().mButtonPressedTime = 0;
                    }
                    else if (chip::System::SystemClock().GetMonotonicMilliseconds64().count() - GetAppTask().mButtonPressedTime >
                             APP_BUTTON_PRESS_LONG)
                    {

                        size_t saved_value_len = 0;

                        ef_get_env_blob(APP_REBOOT_RESET_COUNT_KEY, &resetCnt, sizeof(resetCnt), &saved_value_len);
                        if (resetCnt >= APP_REBOOT_RESET_COUNT)
                        {
                            GetAppTask().PostEvent(APP_EVENT_BTN_FACTORY_RESET_IND);
                        }

                        /** a power cycle during factory reset indication state will quit factory reset operation */
                        resetCnt = 0;
                        ef_set_env_blob(APP_REBOOT_RESET_COUNT_KEY, &resetCnt, sizeof(resetCnt));
                    }
                }
#else
#ifdef LED_BTN_RESET
                if (ButtonPressed())
                {
                    if (!GetAppTask().mIsFactoryResetIndicat &&
                        chip::System::SystemClock().GetMonotonicMilliseconds64().count() - GetAppTask().mButtonPressedTime >=
                            APP_BUTTON_PRESS_SHORT)
                    {
                        GetAppTask().PostEvent(APP_EVENT_BTN_FACTORY_RESET_IND);
                    }
                }
                else
                {
                    GetAppTask().PostEvent(APP_EVENT_BTN_FACTORY_RESET_CANCEL);
                }
#endif
#endif
            }
        }

        StartTimer();
    }
}

void AppTask::IdentifyStartHandler(Identify *)
{
    GetAppTask().PostEvent(APP_EVENT_IDENTIFY_START);
}

void AppTask::IdentifyStopHandler(Identify *)
{
    GetAppTask().PostEvent(APP_EVENT_IDENTIFY_STOP);
}

void AppTask::IdentifyHandleOp(app_event_t event)
{
    static uint32_t identifyState = 0;

    if (APP_EVENT_IDENTIFY_START & event)
    {
        identifyState = 1;
        ChipLogProgress(NotSpecified, "identify start");
    }

    if ((APP_EVENT_IDENTIFY_IDENTIFY & event) && identifyState)
    {
        sLightLED.Toggle();
        ChipLogProgress(NotSpecified, "identify");
    }

    if (APP_EVENT_IDENTIFY_STOP & event)
    {
        identifyState = 0;
        LightingUpdate(APP_EVENT_LIGHTING_GO_THROUGH);
        ChipLogProgress(NotSpecified, "identify stop");
    }
}

void AppTask::ButtonEventHandler(uint8_t btnIdx, uint8_t btnAction)
{
    GetAppTask().PostEvent(APP_EVENT_FACTORY_RESET);
}

#ifdef LED_BTN_RESET
hosal_gpio_dev_t gpio_key = { .port = LED_BTN_RESET, .config = INPUT_HIGH_IMPEDANCE, .priv = NULL };

void AppTask::ButtonInit(void)
{
    GetAppTask().mButtonPressedTime     = 0;
    GetAppTask().mIsFactoryResetIndicat = false;

    hosal_gpio_init(&gpio_key);
    hosal_gpio_irq_set(&gpio_key, HOSAL_IRQ_TRIG_POS_PULSE, GetAppTask().ButtonEventHandler, NULL);
}

bool AppTask::ButtonPressed(void)
{
    uint8_t val = 1;
    hosal_gpio_input_get(&gpio_key, &val);
    return val == 1;
}

void AppTask::ButtonEventHandler(void * arg)
{
    uint32_t presstime;
    if (ButtonPressed())
    {
        hosal_gpio_irq_set(&gpio_key, HOSAL_IRQ_TRIG_NEG_LEVEL, GetAppTask().ButtonEventHandler, NULL);

        GetAppTask().mButtonPressedTime = chip::System::SystemClock().GetMonotonicMilliseconds64().count();
        GetAppTask().PostEvent(APP_EVENT_BTN_FACTORY_RESET_PRESS);
    }
    else
    {
        hosal_gpio_irq_set(&gpio_key, HOSAL_IRQ_TRIG_POS_PULSE, GetAppTask().ButtonEventHandler, NULL);

        if (GetAppTask().mButtonPressedTime)
        {

            presstime = chip::System::SystemClock().GetMonotonicMilliseconds64().count() - GetAppTask().mButtonPressedTime;
            if (presstime >= APP_BUTTON_PRESS_LONG)
            {
                GetAppTask().PostEvent(APP_EVENT_FACTORY_RESET);
            }
            else if (presstime <= APP_BUTTON_PRESS_SHORT && presstime >= APP_BUTTON_PRESS_JITTER)
            {
                GetAppTask().PostEvent(APP_EVENT_BTN_SHORT);
            }
            else
            {
                GetAppTask().PostEvent(APP_EVENT_BTN_FACTORY_RESET_CANCEL);
            }
        }

        GetAppTask().mButtonPressedTime = 0;
    }
}
#endif
