/**
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *
 *    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 <app/util/af-event.h>

#include <app/util/af.h>
#include <app/util/attribute-storage.h>

#include <platform/CHIPDeviceLayer.h>

#define EMBER_MAX_EVENT_CONTROL_DELAY_MS (UINT32_MAX / 2)
#define EMBER_MAX_EVENT_CONTROL_DELAY_QS (EMBER_MAX_EVENT_CONTROL_DELAY_MS >> 8)
#define EMBER_MAX_EVENT_CONTROL_DELAY_MINUTES (EMBER_MAX_EVENT_CONTROL_DELAY_MS >> 16)

#include <app-common/zap-generated/callback.h>

#include <zap-generated/af-gen-event.h>

using namespace chip;

struct EmberEventData
{
    /** The control structure for the event. */
    EmberEventControl * control;
    /** The procedure to call when the event fires. */
    void (*handler)(void);
};

// *****************************************************************************
// Globals

#ifdef EMBER_AF_GENERATED_EVENT_CODE
EMBER_AF_GENERATED_EVENT_CODE
#endif // EMBER_AF_GENERATED_EVENT_CODE

#if defined(EMBER_AF_GENERATED_EVENT_CONTEXT)
uint16_t emAfAppEventContextLength        = EMBER_AF_EVENT_CONTEXT_LENGTH;
EmberAfEventContext emAfAppEventContext[] = { EMBER_AF_GENERATED_EVENT_CONTEXT };
#endif // EMBER_AF_GENERATED_EVENT_CONTEXT

const char * emAfEventStrings[] = {

#ifdef EMBER_AF_GENERATED_EVENTS
    EMBER_AF_GENERATED_EVENT_STRINGS
#endif

    nullptr,
};

EmberEventData emAfEvents[] = {

#ifdef EMBER_AF_GENERATED_EVENTS
    EMBER_AF_GENERATED_EVENTS
#endif

    { nullptr, nullptr }
};

void EventControlHandler(chip::System::Layer * systemLayer, void * appState)
{
    EmberEventControl * control = reinterpret_cast<EmberEventControl *>(appState);
    if (control->status != EMBER_EVENT_INACTIVE)
    {
        control->status = EMBER_EVENT_INACTIVE;

        if (control->callback != nullptr)
        {
            (control->callback)(control->endpoint);
            return;
        }

        for (const EmberEventData & event : emAfEvents)
        {
            if (event.control != control)
                continue;
            control->status = EMBER_EVENT_INACTIVE;
            event.handler();
            break;
        }
    }
}

// *****************************************************************************
// Functions

static EmberAfEventContext * findEventContext(EndpointId endpoint, ClusterId clusterId, bool isClient)
{
#if defined(EMBER_AF_GENERATED_EVENT_CONTEXT)
    uint16_t i;
    for (i = 0; i < emAfAppEventContextLength; i++)
    {
        EmberAfEventContext * context = &(emAfAppEventContext[i]);
        if (context->endpoint == endpoint && context->clusterId == clusterId && context->isClient == isClient)
        {
            return context;
        }
    }
#endif // EMBER_AF_GENERATED_EVENT_CONTEXT
    return nullptr;
}

EmberStatus emberEventControlSetDelayMS(EmberEventControl * control, uint32_t delayMs)
{
    if (delayMs <= EMBER_MAX_EVENT_CONTROL_DELAY_MS)
    {
        control->status = EMBER_EVENT_MS_TIME;
#if !CHIP_DEVICE_LAYER_NONE
        chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Milliseconds32(delayMs), EventControlHandler, control);
#endif
    }
    else
    {
        return EMBER_BAD_ARGUMENT;
    }
    return EMBER_SUCCESS;
}

void emberEventControlSetInactive(EmberEventControl * control)
{
    if (control->status != EMBER_EVENT_INACTIVE)
    {
        control->status = EMBER_EVENT_INACTIVE;
#if !CHIP_DEVICE_LAYER_NONE
        chip::DeviceLayer::SystemLayer().CancelTimer(EventControlHandler, control);
#endif
    }
}

bool emberEventControlGetActive(EmberEventControl * control)
{
    return control->status != EMBER_EVENT_INACTIVE;
}

void emberEventControlSetActive(EmberEventControl * control)
{
    control->status = EMBER_EVENT_ZERO_DELAY;
#if !CHIP_DEVICE_LAYER_NONE
    chip::DeviceLayer::SystemLayer().ScheduleWork(EventControlHandler, control);
#endif
}

EmberStatus emberAfScheduleTickExtended(EndpointId endpoint, ClusterId clusterId, bool isClient, uint32_t delayMs,
                                        EmberAfEventPollControl pollControl, EmberAfEventSleepControl sleepControl)
{
    EmberAfEventContext * context = findEventContext(endpoint, clusterId, isClient);

    // Disabled endpoints cannot schedule events.  This will catch the problem in
    // simulation.
    EMBER_TEST_ASSERT(emberAfEndpointIsEnabled(endpoint));

    if (context != nullptr && emberAfEndpointIsEnabled(endpoint) &&
        (emberEventControlSetDelayMS(context->eventControl, delayMs) == EMBER_SUCCESS))
    {
        context->pollControl  = pollControl;
        context->sleepControl = sleepControl;
        return EMBER_SUCCESS;
    }
    return EMBER_BAD_ARGUMENT;
}

EmberStatus emberAfScheduleClusterTick(EndpointId endpoint, ClusterId clusterId, bool isClient, uint32_t delayMs,
                                       EmberAfEventSleepControl sleepControl)
{
    return emberAfScheduleTickExtended(endpoint, clusterId, isClient, delayMs,
                                       (sleepControl == EMBER_AF_OK_TO_HIBERNATE ? EMBER_AF_LONG_POLL : EMBER_AF_SHORT_POLL),
                                       (sleepControl == EMBER_AF_STAY_AWAKE ? EMBER_AF_STAY_AWAKE : EMBER_AF_OK_TO_SLEEP));
}

EmberStatus emberAfScheduleServerTickExtended(EndpointId endpoint, ClusterId clusterId, uint32_t delayMs,
                                              EmberAfEventPollControl pollControl, EmberAfEventSleepControl sleepControl)
{
    return emberAfScheduleTickExtended(endpoint, clusterId, EMBER_AF_SERVER_CLUSTER_TICK, delayMs, pollControl, sleepControl);
}

EmberStatus emberAfScheduleServerTick(EndpointId endpoint, ClusterId clusterId, uint32_t delayMs)
{
    return emberAfScheduleServerTickExtended(endpoint, clusterId, delayMs, EMBER_AF_LONG_POLL, EMBER_AF_OK_TO_SLEEP);
}

EmberStatus emberAfDeactivateClusterTick(EndpointId endpoint, ClusterId clusterId, bool isClient)
{
    EmberAfEventContext * context = findEventContext(endpoint, clusterId, isClient);
    if (context != nullptr)
    {
        emberEventControlSetInactive(context->eventControl);
        return EMBER_SUCCESS;
    }
    return EMBER_BAD_ARGUMENT;
}

EmberStatus emberAfDeactivateServerTick(EndpointId endpoint, ClusterId clusterId)
{
    return emberAfDeactivateClusterTick(endpoint, clusterId, EMBER_AF_SERVER_CLUSTER_TICK);
}
