/**
 *
 *    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 "ias-zone-server.h"
#include <app-common/zap-generated/att-storage.h>
#include <app-common/zap-generated/attribute-id.h>
#include <app-common/zap-generated/attribute-type.h>
#include <app-common/zap-generated/callback.h>
#include <app-common/zap-generated/cluster-objects.h>
#include <app-common/zap-generated/command-id.h>
#include <app-common/zap-generated/ids/Clusters.h>
#include <app/CommandHandler.h>
#include <app/ConcreteCommandPath.h>
#include <app/util/af-event.h>
#include <app/util/af.h>
#include <app/util/binding-table.h>
#include <app/util/util.h>
#include <system/SystemLayer.h>

using namespace chip;
using namespace chip::app::Clusters;
using namespace chip::app::Clusters::IasZone;

#define UNDEFINED_ZONE_ID 0xFF
#define DELAY_TIMER_MS (1 * MILLISECOND_TICKS_PER_SECOND)
#define IAS_ZONE_SERVER_PAYLOAD_COMMAND_IDX 0x02
#define ZCL_FRAME_CONTROL_IDX 0x00

#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
#if defined(EMBER_AF_PLUGIN_WWAH_APP_EVENT_RETRY_MANAGER)
#define NUM_QUEUE_ENTRIES EMBER_AF_PLUGIN_WWAH_APP_EVENT_RETRY_MANAGER_QUEUE_SIZE
#else
#define NUM_QUEUE_ENTRIES EMBER_AF_PLUGIN_IAS_ZONE_SERVER_QUEUE_DEPTH
#endif
#else
#define NUM_QUEUE_ENTRIES 0
#endif

#define DEFAULT_ENROLLMENT_METHOD EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_REQUEST

// TODO: Need to figure out what needs to happen wrt HAL tokens here, but for
// now define ESZP_HOST to disable it.  See
// https://github.com/project-chip/connectedhomeip/issues/3275
#define EZSP_HOST

typedef struct
{
    EndpointId endpoint;
    uint16_t status;
    System::Clock::Timestamp eventTime;
} IasZoneStatusQueueEntry;

typedef struct
{
    uint8_t entriesInQueue;
    uint8_t startIdx;
    uint8_t lastIdx;
    IasZoneStatusQueueEntry buffer[NUM_QUEUE_ENTRIES];
} IasZoneStatusQueue;

//-----------------------------------------------------------------------------
// Globals

EmberEventControl emberAfPluginIasZoneServerManageQueueEventControl;
static EmberAfIasZoneEnrollmentMode enrollmentMethod;

#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
IasZoneStatusQueue messageQueue;

// Status queue retry parameters
typedef struct
{
    IasZoneStatusQueueRetryConfig config;
    uint32_t currentBackoffTimeSec;
    uint8_t currentRetryCount;
} IasZoneStatusQueueRetryParameters;

// Set up status queue retry parameters.
IasZoneStatusQueueRetryParameters queueRetryParams = {
    .config = { .firstBackoffTimeSec   = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_FIRST_BACKOFF_TIME_SEC,
                .backoffSeqCommonRatio = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_BACKOFF_SEQUENCE_COMMON_RATIO,
                .maxBackoffTimeSec     = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MAX_BACKOFF_TIME_SEC,
#ifdef EMBER_AF_PLUGIN_IAS_ZONE_SERVER_UNLIMITED_RETRIES
                .unlimitedRetries = true,
#else
                .unlimitedRetries = false,
#endif
                .maxRetryAttempts = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MAX_RETRY_ATTEMPTS },
    .currentBackoffTimeSec = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_FIRST_BACKOFF_TIME_SEC,
    .currentRetryCount     = 0,
};

static void resetCurrentQueueRetryParams(void)
{
    queueRetryParams.currentRetryCount     = 0;
    queueRetryParams.currentBackoffTimeSec = queueRetryParams.config.firstBackoffTimeSec;
}

#endif // EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE

//-----------------------------------------------------------------------------
// Forward declarations

static void setZoneId(EndpointId endpoint, uint8_t zoneId);
static bool areZoneServerAttributesNonVolatile(EndpointId endpoint);
static bool isValidEnrollmentMode(EmberAfIasZoneEnrollmentMode method);
#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
static uint16_t computeElapsedTimeQs(IasZoneStatusQueueEntry * entry);
static void bufferInit(IasZoneStatusQueue * ring);
static int16_t copyToBuffer(IasZoneStatusQueue * ring, const IasZoneStatusQueueEntry * entry);
static int16_t popFromBuffer(IasZoneStatusQueue * ring, IasZoneStatusQueueEntry * entry);
#endif

// TODO: https://github.com/project-chip/connectedhomeip/issues/3276 needs to be
// fixed to implement this for real.
EmberNetworkStatus emberAfNetworkState(void)
{
    return EMBER_JOINED_NETWORK;
}

//-----------------------------------------------------------------------------
// Functions

static EmberStatus sendToClient(EndpointId endpoint)
{
    EmberStatus status;

    // If the device is not a network, there is no one to send to, so do nothing
    if (emberAfNetworkState() != EMBER_JOINED_NETWORK)
    {
        return EMBER_NETWORK_DOWN;
    }

    // Remote endpoint need not be set, since it will be provided by the call to
    // emberAfSendCommandUnicastToBindings()
    emberAfSetCommandEndpoints(endpoint, 0);

    // TODO: Figure out how this sending should actually work in Matter.
#if 0
    // A binding table entry is created on Zone Enrollment for each endpoint, so
    // a simple call to SendCommandUnicastToBinding will handle determining the
    // destination endpoint, address, etc for us.
    status = emberAfSendCommandUnicastToBindings();
#else
    status     = EMBER_ERR_FATAL;
#endif

    if (EMBER_SUCCESS != status)
    {
        return status;
    }

    return status;
}

static void enrollWithClient(EndpointId endpoint)
{
    EmberStatus status;
    emberAfFillExternalBuffer((ZCL_CLUSTER_SPECIFIC_COMMAND | ZCL_FRAME_CONTROL_SERVER_TO_CLIENT), IasZone::Id,
                              ZCL_ZONE_ENROLL_REQUEST_COMMAND_ID, "vv", EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ZONE_TYPE,
                              EMBER_AF_MANUFACTURER_CODE);
    status = sendToClient(endpoint);
    if (status == EMBER_SUCCESS)
    {
        emberAfIasZoneClusterPrintln("Sent enroll request to IAS Zone client.");
    }
    else
    {
        emberAfIasZoneClusterPrintln("Error sending enroll request: 0x%x\n", status);
    }
}

Protocols::InteractionModel::Status
MatterIasZoneClusterServerPreAttributeChangedCallback(const app::ConcreteAttributePath & attributePath,
                                                      EmberAfAttributeType attributeType, uint16_t size, uint8_t * value)
{
    uint8_t i;
    bool zeroAddress;
    EmberBindingTableEntry bindingEntry;
    NodeId destNodeId;
    EndpointId endpoint   = attributePath.mEndpointId;
    uint8_t ieeeAddress[] = { 0, 0, 0, 0, 0, 0, 0, 0 };

    // If this is not a CIE Address write, the CIE address has already been
    // written, or the IAS Zone server is already enrolled, do nothing.
    if (attributePath.mAttributeId != ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID || emberAfCurrentCommand() == nullptr)
    {
        return Protocols::InteractionModel::Status::Success;
    }

    memcpy(&destNodeId, value, sizeof(NodeId));

    // Create the binding table entry

    // This code assumes that the endpoint and device that is setting the CIE
    // address is the CIE device itself, and as such the remote endpoint to bind
    // to is the endpoint that generated the attribute change.  This
    // assumption is made based on analysis of the behavior of CIE devices
    // currently existing in the field.
    bindingEntry.type      = EMBER_UNICAST_BINDING;
    bindingEntry.local     = endpoint;
    bindingEntry.clusterId = MakeOptional(IasZone::Id);
    bindingEntry.remote    = emberAfCurrentCommand()->apsFrame->sourceEndpoint;
    bindingEntry.nodeId    = destNodeId;

    bool foundSameEntry = false;
    // Cycle through the binding table until we find a valid entry that is not
    // being used, then use the created entry to make the bind.
    for (const auto & currentBind : BindingTable::GetInstance())
    {
        // If the binding table entry created based on the response already exists
        // do nothing.
        if ((currentBind.local == bindingEntry.local) && (currentBind.clusterId == bindingEntry.clusterId) &&
            (currentBind.remote == bindingEntry.remote) && (currentBind.type == bindingEntry.type))
        {
            foundSameEntry = true;
            break;
        }
    }

    if (!foundSameEntry)
    {
        BindingTable::GetInstance().Add(bindingEntry);
    }

    zeroAddress = true;
    emberAfReadServerAttribute(endpoint, IasZone::Id, ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID, (uint8_t *) ieeeAddress, 8);
    for (i = 0; i < 8; i++)
    {
        if (ieeeAddress[i] != 0)
        {
            zeroAddress = false;
        }
    }
    emberAfAppPrint("\nzero address: %d\n", zeroAddress);

    if ((zeroAddress == true) && (enrollmentMethod == EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_REQUEST))
    {
        // Only send the enrollment request if the mode is AUTO-ENROLL-REQUEST.
        // We need to delay to get around a bug where we can't send a command
        // at this point because then the Write Attributes response will not
        // be sent.  But we also delay to give the client time to configure us.
        emberAfIasZoneClusterPrintln("Sending enrollment after %d ms", DELAY_TIMER_MS);
        emberAfScheduleServerTickExtended(endpoint, IasZone::Id, DELAY_TIMER_MS, EMBER_AF_SHORT_POLL, EMBER_AF_STAY_AWAKE);
    }

    return Protocols::InteractionModel::Status::Success;
}

EmberAfStatus emberAfPluginIasZoneClusterSetEnrollmentMethod(EndpointId endpoint, EmberAfIasZoneEnrollmentMode method)
{
    EmberAfStatus status;

    if (emberAfIasZoneClusterAmIEnrolled(endpoint))
    {
        emberAfIasZoneClusterPrintln("Error: Already enrolled");
        status = EMBER_ZCL_STATUS_UNSUPPORTED_ACCESS;
    }
    else if (!isValidEnrollmentMode(method))
    {
        emberAfIasZoneClusterPrintln("Invalid IAS Zone Server Enrollment Mode: %d", method);
        status = EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    else
    {
        enrollmentMethod = method;
#ifndef EZSP_HOST
        halCommonSetToken(TOKEN_PLUGIN_IAS_ZONE_SERVER_ENROLLMENT_METHOD, &enrollmentMethod);
#endif
        emberAfIasZoneClusterPrintln("IAS Zone Server Enrollment Mode: %d", method);
        status = EMBER_ZCL_STATUS_SUCCESS;
    }
    return status;
}

static bool isValidEnrollmentMode(EmberAfIasZoneEnrollmentMode method)
{
    return ((method == EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_TRIP_TO_PAIR) ||
            (method == EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_AUTO_ENROLLMENT_RESPONSE) ||
            (method == EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_REQUEST));
}

bool emberAfIasZoneClusterAmIEnrolled(EndpointId endpoint)
{
    EmberAfIasZoneState zoneState = EMBER_ZCL_IAS_ZONE_STATE_NOT_ENROLLED; // Clear this out completely.
    EmberAfStatus status;
    status = emberAfReadServerAttribute(endpoint, IasZone::Id, ZCL_ZONE_STATE_ATTRIBUTE_ID, (unsigned char *) &zoneState,
                                        1); // uint8_t size

    return (status == EMBER_ZCL_STATUS_SUCCESS && zoneState == EMBER_ZCL_IAS_ZONE_STATE_ENROLLED);
}

static void updateEnrollState(EndpointId endpoint, bool enrolled)
{
    EmberAfIasZoneState zoneState = (enrolled ? EMBER_ZCL_IAS_ZONE_STATE_ENROLLED : EMBER_ZCL_IAS_ZONE_STATE_NOT_ENROLLED);

    emberAfWriteServerAttribute(endpoint, IasZone::Id, ZCL_ZONE_STATE_ATTRIBUTE_ID, (uint8_t *) &zoneState,
                                ZCL_INT8U_ATTRIBUTE_TYPE);
    emberAfIasZoneClusterPrintln("IAS Zone Server State: %pEnrolled", (enrolled ? "" : "NOT "));
}

bool emberAfIasZoneClusterZoneEnrollResponseCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath,
                                                     const Commands::ZoneEnrollResponse::DecodableType & commandData)
{
    auto & enrollResponseCode = commandData.enrollResponseCode;
    auto & zoneId             = commandData.zoneId;

    EndpointId endpoint;
    uint8_t epZoneId;
    EmberAfStatus status;

    endpoint = emberAfCurrentEndpoint();
    status   = emberAfReadServerAttribute(endpoint, IasZone::Id, ZCL_ZONE_ID_ATTRIBUTE_ID, &epZoneId, sizeof(uint8_t));
    if (status == EMBER_ZCL_STATUS_SUCCESS)
    {
        if (enrollResponseCode == EMBER_ZCL_IAS_ENROLL_RESPONSE_CODE_SUCCESS)
        {
            updateEnrollState(endpoint, true);
            setZoneId(endpoint, zoneId);
        }
        else
        {
            updateEnrollState(endpoint, false);
            setZoneId(endpoint, UNDEFINED_ZONE_ID);
        }

        return true;
    }

    emberAfAppPrintln("ERROR: IAS Zone Server unable to read zone ID attribute");
    return true;
}

static EmberStatus sendZoneUpdate(uint16_t zoneStatus, uint16_t timeSinceStatusOccurredQs, EndpointId endpoint)
{
    EmberStatus status;

    if (!emberAfIasZoneClusterAmIEnrolled(endpoint))
    {
        return EMBER_INVALID_CALL;
    }
    emberAfFillExternalBuffer((ZCL_CLUSTER_SPECIFIC_COMMAND | ZCL_FRAME_CONTROL_SERVER_TO_CLIENT), IasZone::Id,
                              ZCL_ZONE_STATUS_CHANGE_NOTIFICATION_COMMAND_ID, "vuuv", zoneStatus,
                              0 /*extended status, must be zero per spec*/, emberAfPluginIasZoneServerGetZoneId(endpoint),
                              timeSinceStatusOccurredQs /* called "delay" in the spec */);
    status = sendToClient(endpoint);

    return status;
}

#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
static void addNewEntryToQueue(const IasZoneStatusQueueEntry * newEntry)
{
    emberAfIasZoneClusterPrintln("Adding new entry to queue");
    copyToBuffer(&messageQueue, newEntry);
}
#endif

EmberStatus emberAfPluginIasZoneServerUpdateZoneStatus(EndpointId endpoint, uint16_t newStatus, uint16_t timeSinceStatusOccurredQs)
{
#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
    IasZoneStatusQueueEntry newBufferEntry;
    newBufferEntry.endpoint  = endpoint;
    newBufferEntry.status    = newStatus;
    newBufferEntry.eventTime = System::SystemClock().GetMonotonicTimestamp();
#endif
    EmberStatus sendStatus = EMBER_SUCCESS;

    emberAfWriteServerAttribute(endpoint, IasZone::Id, ZCL_ZONE_STATUS_ATTRIBUTE_ID, (uint8_t *) &newStatus,
                                ZCL_INT16U_ATTRIBUTE_TYPE);

    if (enrollmentMethod == EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_TRIP_TO_PAIR)
    {
        // If unenrolled, send Zone Enroll Request command.
        if (!emberAfIasZoneClusterAmIEnrolled(endpoint))
        {
            emberAfScheduleServerTick(endpoint, IasZone::Id, DELAY_TIMER_MS);
            // Don't send the zone status update since not enrolled.
            return EMBER_SUCCESS;
        }
    }

#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
    // If there are items in the queue waiting to send, this event should not
    // be transmitted, as that could cause the client to receive the events out
    // of order.  Instead, just add the device to the queue
    if (messageQueue.entriesInQueue == 0)
    {
        sendStatus = sendZoneUpdate(newStatus, timeSinceStatusOccurredQs, endpoint);
    }
    else
    {
        // Add a new element to the status queue and depending on the network state
        // either try to resend the first element in the queue immediately or try to
        // restart the parent research pattern.
        addNewEntryToQueue(&newBufferEntry);

        EmberNetworkStatus networkState = emberAfNetworkState();

        if (networkState == EMBER_JOINED_NETWORK_NO_PARENT)
        {
            emberAfStartMoveCallback();
        }
        else if (networkState == EMBER_JOINED_NETWORK)
        {
            resetCurrentQueueRetryParams();
            emberEventControlSetActive(&emberAfPluginIasZoneServerManageQueueEventControl);
        }

        return EMBER_SUCCESS;
    }

#else
    sendStatus = sendZoneUpdate(newStatus, timeSinceStatusOccurredQs, endpoint);
#endif

    if (sendStatus == EMBER_SUCCESS)
    {
#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
        // Add a new entry to the zoneUpdate buffer
        addNewEntryToQueue(&newBufferEntry);
#endif
    }
    else
    {
        // If we're not on a network and never were, we don't need to do anything.
        // If we used to be on a network and can't talk to our parent, we should
        // try to rejoin the network and add the message to the queue
        if (emberAfNetworkState() == EMBER_JOINED_NETWORK_NO_PARENT)
        {
            emberAfStartMoveCallback();
#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
            // Add a new entry to the zoneUpdate buffer
            addNewEntryToQueue(&newBufferEntry);
#endif
        }
        emberAfIasZoneClusterPrintln("Failed to send IAS Zone update. Err 0x%x", sendStatus);
    }
    return sendStatus;
}

void emberAfPluginIasZoneServerManageQueueEventHandler(void)
{
#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
    IasZoneStatusQueueEntry * bufferStart;
    uint16_t status;
    uint16_t elapsedTimeQs;
    uint16_t airTimeRemainingMs;

    // If the queue was emptied without our interaction, do nothing
    if (messageQueue.entriesInQueue == 0)
    {
        emberEventControlSetInactive(&emberAfPluginIasZoneServerManageQueueEventControl);
        return;
    }

    // Otherwise, pull out the first item and attempt to retransmit it.  The
    // message complete callback will handle removing items from the queue

    // To prevent an activity storm from flooding with retry requests, only
    // re-send a message if it's been at least
    // EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MIN_OTA_TIME_MS since it was sent.
    bufferStart   = &(messageQueue.buffer[messageQueue.startIdx]);
    elapsedTimeQs = computeElapsedTimeQs(bufferStart);

    if (elapsedTimeQs < (EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MIN_OTA_TIME_MS / (MILLISECOND_TICKS_PER_SECOND / 4)))
    {
        airTimeRemainingMs = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MIN_OTA_TIME_MS - (elapsedTimeQs * MILLISECOND_TICKS_PER_SECOND / 4);
        emberAfIasZoneClusterPrintln("Not enough time passed for a retry, sleeping %d more mS", airTimeRemainingMs);
        emberEventControlSetDelayMS(emberAfPluginIasZoneServerManageQueueEventControl, airTimeRemainingMs);
    }
    else
    {
        status = bufferStart->status;
        emberAfIasZoneClusterPrintln("Attempting to resend a queued zone status update (status: 0x%02X, "
                                     "event time (s): %d) with time of %d. Retry count: %d",
                                     bufferStart->status, bufferStart->eventTime / MILLISECOND_TICKS_PER_SECOND, elapsedTimeQs,
                                     queueRetryParams.currentRetryCount);
        sendZoneUpdate(status, elapsedTimeQs, bufferStart->endpoint);
        emberEventControlSetInactive(&emberAfPluginIasZoneServerManageQueueEventControl);
    }
#else
    emberEventControlSetInactive(&emberAfPluginIasZoneServerManageQueueEventControl);
#endif
}

void emberAfIasZoneClusterServerInitCallback(EndpointId endpoint)
{
    EmberAfIasZoneType zoneType;
    if (!areZoneServerAttributesNonVolatile(endpoint))
    {
        emberAfAppPrint("WARNING: ATTRIBUTES ARE NOT BEING STORED IN FLASH! ");
        emberAfAppPrintln("DEVICE WILL NOT FUNCTION PROPERLY AFTER REBOOTING!!");
    }

#ifndef EZSP_HOST
    halCommonGetToken(&enrollmentMethod, TOKEN_PLUGIN_IAS_ZONE_SERVER_ENROLLMENT_METHOD);
#else
    enrollmentMethod = DEFAULT_ENROLLMENT_METHOD;
#endif
    if (!isValidEnrollmentMode(enrollmentMethod))
    {
        // Default Enrollment Method to AUTO-ENROLL-REQUEST.
        enrollmentMethod = DEFAULT_ENROLLMENT_METHOD;
    }

#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
    bufferInit(&messageQueue);
#endif

    zoneType = (EmberAfIasZoneType) EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ZONE_TYPE;
    emberAfWriteAttribute(endpoint, IasZone::Id, ZCL_ZONE_TYPE_ATTRIBUTE_ID, (uint8_t *) &zoneType, ZCL_INT16U_ATTRIBUTE_TYPE);

    emberAfPluginIasZoneServerUpdateZoneStatus(endpoint,
                                               0,  // status: All alarms cleared
                                               0); // time since status occurred
}

void emberAfIasZoneClusterServerTickCallback(EndpointId endpoint)
{
    enrollWithClient(endpoint);
}

uint8_t emberAfPluginIasZoneServerGetZoneId(EndpointId endpoint)
{
    uint8_t zoneId = UNDEFINED_ZONE_ID;
    emberAfReadServerAttribute(endpoint, IasZone::Id, ZCL_ZONE_ID_ATTRIBUTE_ID, &zoneId,
                               emberAfGetDataSize(ZCL_INT8U_ATTRIBUTE_TYPE));
    return zoneId;
}

//------------------------------------------------------------------------------
//
// This function will verify that all attributes necessary for the IAS zone
// server to properly retain functionality through a power failure are
// non-volatile.
//
//------------------------------------------------------------------------------
static bool areZoneServerAttributesNonVolatile(EndpointId endpoint)
{
    if (emberAfIsKnownVolatileAttribute(endpoint, IasZone::Id, Attributes::IasCieAddress::Id) ||
        emberAfIsKnownVolatileAttribute(endpoint, IasZone::Id, Attributes::ZoneState::Id) ||
        emberAfIsKnownVolatileAttribute(endpoint, IasZone::Id, Attributes::ZoneType::Id) ||
        emberAfIsKnownVolatileAttribute(endpoint, IasZone::Id, Attributes::ZoneId::Id))
    {
        return false;
    }

    return true;
}

static void setZoneId(EndpointId endpoint, uint8_t zoneId)
{
    emberAfIasZoneClusterPrintln("IAS Zone Server Zone ID: 0x%X", zoneId);
    emberAfWriteServerAttribute(endpoint, IasZone::Id, ZCL_ZONE_ID_ATTRIBUTE_ID, &zoneId, ZCL_INT8U_ATTRIBUTE_TYPE);
}

static void unenrollSecurityDevice(EndpointId endpoint)
{
    uint8_t ieeeAddress[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
    uint16_t zoneType     = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ZONE_TYPE;

    emberAfWriteServerAttribute(endpoint, IasZone::Id, ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID, (uint8_t *) ieeeAddress,
                                ZCL_NODE_ID_ATTRIBUTE_TYPE);

    emberAfWriteServerAttribute(endpoint, IasZone::Id, ZCL_ZONE_TYPE_ATTRIBUTE_ID, (uint8_t *) &zoneType,
                                ZCL_INT16U_ATTRIBUTE_TYPE);

    setZoneId(endpoint, UNDEFINED_ZONE_ID);
    // Restore the enrollment method back to its default value.
    emberAfPluginIasZoneClusterSetEnrollmentMethod(endpoint, DEFAULT_ENROLLMENT_METHOD);
    updateEnrollState(endpoint, false); // enrolled?
}

// If you leave the network, unenroll yourself.
void emberAfPluginIasZoneServerStackStatusCallback(EmberStatus status)
{
    EndpointId endpoint;

    // If the device has left the network, unenroll all endpoints on the device
    // that are servers of the IAS Zone Cluster
    if (status == EMBER_NETWORK_DOWN && emberAfNetworkState() == EMBER_NO_NETWORK)
    {
        for (uint16_t i = 0; i < emberAfEndpointCount(); i++)
        {
            endpoint = emberAfEndpointFromIndex(i);
            if (emberAfContainsServer(endpoint, IasZone::Id))
            {
                unenrollSecurityDevice(endpoint);
            }
        }
    }
    else if (status == EMBER_NETWORK_UP)
    {
#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
        // If we're reconnecting, send any items still in the queue
        emberAfIasZoneClusterPrintln("Rejoined network, retransmiting any queued event");
        emberEventControlSetActive(&emberAfPluginIasZoneServerManageQueueEventControl);
#endif
    }
}

#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
EmberStatus emberAfIasZoneServerConfigStatusQueueRetryParams(IasZoneStatusQueueRetryConfig * retryConfig)
{
    if (!(retryConfig->firstBackoffTimeSec) || (!retryConfig->backoffSeqCommonRatio) ||
        (retryConfig->maxBackoffTimeSec < retryConfig->firstBackoffTimeSec) ||
        (retryConfig->maxBackoffTimeSec > IAS_ZONE_STATUS_QUEUE_RETRY_ABS_MAX_BACKOFF_TIME_SEC) || (!retryConfig->maxRetryAttempts))
    {
        return EMBER_BAD_ARGUMENT;
    }

    queueRetryParams.config.firstBackoffTimeSec   = retryConfig->firstBackoffTimeSec;
    queueRetryParams.config.backoffSeqCommonRatio = retryConfig->backoffSeqCommonRatio;
    queueRetryParams.config.maxBackoffTimeSec     = retryConfig->maxBackoffTimeSec;
    queueRetryParams.config.unlimitedRetries      = retryConfig->unlimitedRetries;
    queueRetryParams.config.maxRetryAttempts      = retryConfig->maxRetryAttempts;

    queueRetryParams.currentBackoffTimeSec = retryConfig->firstBackoffTimeSec;
    queueRetryParams.currentRetryCount     = 0;

    return EMBER_SUCCESS;
}

void emberAfIasZoneServerSetStatusQueueRetryParamsToDefault(void)
{
    queueRetryParams.config.firstBackoffTimeSec   = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_FIRST_BACKOFF_TIME_SEC;
    queueRetryParams.config.backoffSeqCommonRatio = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_BACKOFF_SEQUENCE_COMMON_RATIO;
    queueRetryParams.config.maxBackoffTimeSec     = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MAX_BACKOFF_TIME_SEC;
#ifdef EMBER_AF_PLUGIN_IAS_ZONE_SERVER_UNLIMITED_RETRIES
    queueRetryParams.config.unlimitedRetries = true;
#else
    queueRetryParams.config.unlimitedRetries = false;
#endif
    queueRetryParams.config.maxRetryAttempts = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MAX_RETRY_ATTEMPTS;

    queueRetryParams.currentBackoffTimeSec = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_FIRST_BACKOFF_TIME_SEC;
    queueRetryParams.currentRetryCount     = 0;
}

void emberAfIasZoneServerDiscardPendingEventsInStatusQueue(void)
{
    emberEventControlSetInactive(&emberAfPluginIasZoneServerManageQueueEventControl);
    bufferInit(&messageQueue);
    resetCurrentQueueRetryParams();
}

#if defined(EMBER_AF_PLUGIN_WWAH_APP_EVENT_RETRY_MANAGER)
EmberStatus emberAfWwahAppEventRetryManagerConfigBackoffParamsCallback(uint8_t firstBackoffTimeSeconds,
                                                                       uint8_t backoffSeqCommonRatio,
                                                                       uint32_t maxBackoffTimeSeconds,
                                                                       uint8_t maxRedeliveryAttempts)
{
    IasZoneStatusQueueRetryConfig retryConfig = { firstBackoffTimeSeconds, backoffSeqCommonRatio, maxBackoffTimeSeconds,
                                                  (maxRedeliveryAttempts == 0xFF), maxRedeliveryAttempts };

    // Setting up retry parameters
    return emberAfIasZoneServerConfigStatusQueueRetryParams(&retryConfig);
}

void emberAfWwahAppEventRetryManagerSetBackoffParamsToDefault(void)
{
    emberAfIasZoneServerSetStatusQueueRetryParamsToDefault();
}
#endif // defined(EMBER_AF_PLUGIN_WWAH_APP_EVENT_RETRY_MANAGER)

void emberAfPluginIasZoneServerPrintQueue(void)
{
    emberAfIasZoneClusterPrintln("%d/%d entries", messageQueue.entriesInQueue, NUM_QUEUE_ENTRIES);
    for (int i = 0; i < messageQueue.entriesInQueue; i++)
    {
        emberAfIasZoneClusterPrintln("Entry %d: Endpoint: %d Status: %d EventTimeMs: %d", i, messageQueue.buffer[i].endpoint,
                                     messageQueue.buffer[i].status, messageQueue.buffer[i].eventTime);
    }
}

void emberAfPluginIasZoneServerPrintQueueConfig(void)
{
    emberAfCorePrintln("First backoff time (sec): %d", queueRetryParams.config.firstBackoffTimeSec);
    emberAfCorePrintln("Backoff sequence common ratio: %d", queueRetryParams.config.backoffSeqCommonRatio);
    emberAfCorePrintln("Max backoff time (sec): %d", queueRetryParams.config.maxBackoffTimeSec);
    emberAfCorePrintln("Max redelivery attempts: %d", queueRetryParams.config.maxRetryAttempts);
}

#endif // defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)

// This callback will be generated any time the node receives an ACK or a NAK
// for a message transmitted for the IAS Zone Cluster Server.  Note that this
// will not be called in the case that the message was not delivered to the
// destination when the destination is the only router the node is joined to.
// In that case, the command will never have been sent, as the device will have
// had no router by which to send the command.
void emberAfIasZoneClusterServerMessageSentCallback(const MessageSendDestination & destination, EmberApsFrame * apsFrame,
                                                    uint16_t msgLen, uint8_t * message, EmberStatus status)
{
#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
    uint8_t frameControl;
    CommandId commandId;

    IasZoneStatusQueueEntry dummyEntry;

    // Verify that this response is for a ZoneStatusChangeNotification command
    // by checking the message length, the command and direction bits of the
    // Frame Control byte, and the command ID
    if (msgLen < IAS_ZONE_SERVER_PAYLOAD_COMMAND_IDX)
    {
        return;
    }

    frameControl = message[ZCL_FRAME_CONTROL_IDX];
    if (!(frameControl & ZCL_CLUSTER_SPECIFIC_COMMAND) || !(frameControl & ZCL_FRAME_CONTROL_SERVER_TO_CLIENT))
    {
        return;
    }

    commandId = message[IAS_ZONE_SERVER_PAYLOAD_COMMAND_IDX];
    if (commandId != ZCL_ZONE_STATUS_CHANGE_NOTIFICATION_COMMAND_ID)
    {
        return;
    }

    // If a change status change notification command is not received by the
    // client, delay the option specified amount of time and try to resend it.
    // The event handler will perform the retransmit per the preset queue retry
    // parameters, and the original send request will handle populating the buffer.
    // Do not try to retransmit again if the maximum number of retries attempts
    // is reached, this is however discarded if configured for unlimited retries.
    if ((status == EMBER_DELIVERY_FAILED) &&
        (queueRetryParams.config.unlimitedRetries ||
         (queueRetryParams.currentRetryCount < queueRetryParams.config.maxRetryAttempts)))
    {
        queueRetryParams.currentRetryCount++;

        emberAfIasZoneClusterPrintln("Status command update failed to send... Retrying in %d seconds...",
                                     queueRetryParams.currentBackoffTimeSec);

        // Delay according to the current retransmit backoff time.
        emberEventControlSetDelayMS(emberAfPluginIasZoneServerManageQueueEventControl,
                                    queueRetryParams.currentBackoffTimeSec * MILLISECOND_TICKS_PER_SECOND);

        // The backoff time needs to be increased if the maximum backoff time is not reached yet.
        if ((queueRetryParams.currentBackoffTimeSec * queueRetryParams.config.backoffSeqCommonRatio) <=
            queueRetryParams.config.maxBackoffTimeSec)
        {
            queueRetryParams.currentBackoffTimeSec *= queueRetryParams.config.backoffSeqCommonRatio;
        }
    }
    else
    {
        // If a command message was sent or max redelivery attempts were reached,
        // remove it from the queue and move on to the next queued message until the queue is empty.
        if (status == EMBER_SUCCESS)
        {
            emberAfIasZoneClusterPrintln("\nZone update successful, remove entry from queue");
        }
        else
        {
            emberAfIasZoneClusterPrintln("\nZone update unsuccessful, max retry attempts reached, remove entry from queue");
        }
        popFromBuffer(&messageQueue, &dummyEntry);

        // Reset queue retry parameters.
        resetCurrentQueueRetryParams();

        if (messageQueue.entriesInQueue)
        {
            emberEventControlSetActive(&emberAfPluginIasZoneServerManageQueueEventControl);
        }
    }
#endif
}

#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
static void bufferInit(IasZoneStatusQueue * ring)
{
    ring->entriesInQueue = 0;
    ring->startIdx       = 0;
    ring->lastIdx        = NUM_QUEUE_ENTRIES - 1;
}

// Add the entry to the buffer by copying, returning the index at which it was
// added.  If the buffer is full, return -1, but still copy the entry over the
// last item of the buffer, to ensure that the last item in the buffer is
// always representative of the last known device state.
static int16_t copyToBuffer(IasZoneStatusQueue * ring, const IasZoneStatusQueueEntry * entry)
{
    if (ring->entriesInQueue == NUM_QUEUE_ENTRIES)
    {
        ring->buffer[ring->lastIdx] = *entry;
        return -1;
    }

    // Increment the last pointer.  If it rolls over the size, circle it back to
    // zero.
    ring->lastIdx++;
    if (ring->lastIdx >= NUM_QUEUE_ENTRIES)
    {
        ring->lastIdx = 0;
    }

    ring->buffer[ring->lastIdx].endpoint  = entry->endpoint;
    ring->buffer[ring->lastIdx].status    = entry->status;
    ring->buffer[ring->lastIdx].eventTime = entry->eventTime;

    ring->entriesInQueue++;
    return ring->lastIdx;
}

// Return the idx of the popped entry, or -1 if the buffer was empty.
static int16_t popFromBuffer(IasZoneStatusQueue * ring, IasZoneStatusQueueEntry * entry)
{
    int16_t retVal;

    if (ring->entriesInQueue == 0)
    {
        return -1;
    }

    // Copy out the first entry, then increment the start pointer.  If it rolls
    // over, circle it back to zero.
    *entry = ring->buffer[ring->startIdx];
    retVal = ring->startIdx;

    ring->startIdx++;
    if (ring->startIdx >= NUM_QUEUE_ENTRIES)
    {
        ring->startIdx = 0;
    }

    ring->entriesInQueue--;

    return retVal;
}

uint16_t computeElapsedTimeQs(IasZoneStatusQueueEntry * entry)
{
    System::Clock::Milliseconds64 currentTimeMs = System::SystemClock().GetMonotonicMilliseconds64();
    int64_t deltaTimeMs                         = currentTimeMs.count() - entry->eventTime.count();

    if (deltaTimeMs < 0)
    {
        deltaTimeMs = -deltaTimeMs + (0xFFFFFFFF - currentTimeMs);
    }

    return deltaTimeMs / MILLISECOND_TICKS_PER_QUARTERSECOND;
}
#endif

void MatterIasZonePluginServerInitCallback() {}
