/**
 *
 *    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-id.h>
#include <app-common/zap-generated/cluster-objects.h>
#include <app-common/zap-generated/command-id.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), ZCL_IAS_ZONE_CLUSTER_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(ZCL_IAS_ZONE_CLUSTER_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, ZCL_IAS_ZONE_CLUSTER_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, ZCL_IAS_ZONE_CLUSTER_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_NOT_AUTHORIZED;
    }
    else if (!isValidEnrollmentMode(method))
    {
        emberAfIasZoneClusterPrintln("Invalid IAS Zone Server Enrollment Mode: %d", method);
        status = EMBER_ZCL_STATUS_INVALID_VALUE;
    }
    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, ZCL_IAS_ZONE_CLUSTER_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, ZCL_IAS_ZONE_CLUSTER_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, ZCL_IAS_ZONE_CLUSTER_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), ZCL_IAS_ZONE_CLUSTER_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, ZCL_IAS_ZONE_CLUSTER_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, ZCL_IAS_ZONE_CLUSTER_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, ZCL_IAS_ZONE_CLUSTER_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, ZCL_IAS_ZONE_CLUSTER_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, ZCL_IAS_ZONE_CLUSTER_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, ZCL_IAS_ZONE_CLUSTER_ID, ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID, (uint8_t *) ieeeAddress,
                                ZCL_NODE_ID_ATTRIBUTE_TYPE);

    emberAfWriteServerAttribute(endpoint, ZCL_IAS_ZONE_CLUSTER_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, ZCL_IAS_ZONE_CLUSTER_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() {}
