/**
 *
 *    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.
 */

/**
 *
 *    Copyright (c) 2020 Silicon Labs
 *
 *    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.
 */
/***************************************************************************/
/**
 * @file
 * @brief Code common to both the Host and SOC (system
 *on a chip) versions of the Application Framework.
 *******************************************************************************
 ******************************************************************************/

//#include PLATFORM_HEADER // Micro and compiler specific typedefs and macros

#if defined EZSP_HOST
#include "stack/include/ember-types.h"
#include "stack/include/error.h"
#include "stack/include/library.h"
#else
// Ember stack and related utilities
//#include "stack/include/cbke-crypto-engine.h"
//#include "stack/include/ember.h" // Main stack definitions
#endif

// HAL - hardware abstraction layer
//#include "hal/hal.h"
//#include "plugin/serial/serial.h" // Serial utility APIs

// CLI - command line interface
//#include "app/util/serial/command-interpreter2.h"

#if defined EZSP_HOST
// EZSP - ember serial host protocol
#include "app/util/ezsp/ezsp-protocol.h"
#include "app/util/ezsp/ezsp-utils.h"
#include "app/util/ezsp/ezsp.h"
#include "app/util/ezsp/serial-interface.h"
#endif

// Sub-GHz client, for a last-minute chance to block sending ZCL messgaes within the suspend period
#ifdef EMBER_AF_PLUGIN_SUB_GHZ_CLIENT
#include "app/framework/plugin/sub-ghz-client/sub-ghz-client.h"
#endif

// Sub-GHz server, for an automatic reply if a client attempt to communicate within the suspend period
#ifdef EMBER_AF_PLUGIN_SUB_GHZ_SERVER
#include "app/framework/plugin/sub-ghz-server/sub-ghz-server.h"
#endif

// Fragmentation.
#ifdef EMBER_AF_PLUGIN_FRAGMENTATION
#include "app/framework/plugin/fragmentation/fragmentation.h"
#endif

#ifdef EMBER_AF_PLUGIN_CRITICAL_MESSAGE_QUEUE
#include "app/framework/plugin/critical-message-queue/critical-message-queue.h"
#endif // EMBER_AF_PLUGIN_CRITICAL_MESSAGE_QUEUE

// Service discovery library
//#include "service-discovery.h"

// determines the number of in-clusters and out-clusters based on defines
// in config.h
#include <app/util/af-main.h>

//#include "app/framework/security/af-security.h"
//#include "app/framework/security/crypto-state.h"
#include "app/util/common.h"
#include <app-common/zap-generated/callback.h>
#include <app/util/attribute-storage.h>
#include <app/util/attribute-table.h>
#include <app/util/config.h>
//#include "print.h"
#include <app/util/binding-table.h>
#include <app/util/chip-message-send.h>
#include <app/util/util.h>

using namespace chip;

// Querying the Ember Stack for what libraries are present.
//#include "app/util/common/library.h"

// ZDO - ZigBee Device Object
//#include "app/util/zigbee-framework/zigbee-device-common.h"

//#include "app/framework/plugin/ota-storage-common/ota-storage.h"
//#include "app/framework/plugin/partner-link-key-exchange/partner-link-key-exchange.h"

//------------------------------------------------------------------------------

#define INVALID_MESSAGE_TAG 0xFF

#if defined(EMBER_AF_HAS_COORDINATOR_NETWORK)
#if !defined(EMBER_AF_PLUGIN_CONCENTRATOR)
#error "A Coordinator device (Trust Center) MUST enable the concentrator plugin to function correctly."
#endif
#endif

#ifdef EMBER_AF_GENERATED_PLUGIN_STACK_STATUS_FUNCTION_DECLARATIONS
EMBER_AF_GENERATED_PLUGIN_STACK_STATUS_FUNCTION_DECLARATIONS
#endif

#ifdef EMBER_AF_GENERATED_PLUGIN_MESSAGE_SENT_FUNCTION_DECLARATIONS
EMBER_AF_GENERATED_PLUGIN_MESSAGE_SENT_FUNCTION_DECLARATIONS
#endif

#ifdef EMBER_AF_GENERATED_PLUGIN_ZDO_MESSAGE_RECEIVED_FUNCTION_DECLARATIONS
EMBER_AF_GENERATED_PLUGIN_ZDO_MESSAGE_RECEIVED_FUNCTION_DECLARATIONS
#endif

static CallbackTableEntry messageSentCallbacks[EMBER_AF_MESSAGE_SENT_CALLBACK_TABLE_SIZE];

// We declare this variable 'const' but NOT const.  Those functions that we may use
// this variable would also have to declare it const in order to function
// correctly, which is not the case (e.g. emberFindKeyTableEntry()).
const EmberEUI64 emberAfNullEui64 = { 0, 0, 0, 0, 0, 0, 0, 0 };

//------------------------------------------------------------------------------
// Forward declarations
static uint8_t getMessageSentCallbackIndex(void);
static void invalidateMessageSentCallbackEntry(uint8_t messageTag);
static EmberAfMessageSentFunction getMessageSentCallback(uint8_t tag);

static uint8_t getMessageSentCallbackIndex(void)
{
    uint8_t i;
    for (i = 0; i < EMBER_AF_MESSAGE_SENT_CALLBACK_TABLE_SIZE; i++)
    {
        if (messageSentCallbacks[i].tag == INVALID_MESSAGE_TAG)
        {
            return i;
        }
    }

    return INVALID_MESSAGE_TAG;
}

static void invalidateMessageSentCallbackEntry(uint8_t tag)
{
    uint8_t i;
    for (i = 0; i < EMBER_AF_MESSAGE_SENT_CALLBACK_TABLE_SIZE; i++)
    {
        if (messageSentCallbacks[i].tag == tag)
        {
            messageSentCallbacks[i].tag      = INVALID_MESSAGE_TAG;
            messageSentCallbacks[i].callback = NULL;
            return;
        }
    }
}

static EmberAfMessageSentFunction getMessageSentCallback(uint8_t tag)
{
    uint8_t i;
    for (i = 0; i < EMBER_AF_MESSAGE_SENT_CALLBACK_TABLE_SIZE; i++)
    {
        if (messageSentCallbacks[i].tag == tag)
        {
            return messageSentCallbacks[i].callback;
        }
    }

    return NULL;
}

void emAfInitializeMessageSentCallbackArray(void)
{
    uint8_t i;
    for (i = 0; i < EMBER_AF_MESSAGE_SENT_CALLBACK_TABLE_SIZE; i++)
    {
        messageSentCallbacks[i].tag      = INVALID_MESSAGE_TAG;
        messageSentCallbacks[i].callback = NULL;
    }
}

static EmberStatus send(const MessageSendDestination & destination, EmberApsFrame * apsFrame, uint16_t messageLength,
                        uint8_t * message, bool broadcast, EmberNodeId alias, uint8_t sequence, EmberAfMessageSentFunction callback)
{
    EmberStatus status;
    uint16_t index;
    uint8_t messageSentIndex;
    uint8_t messageTag = INVALID_MESSAGE_TAG;

    // The send APIs only deal with ZCL messages, so they must at least contain
    // the ZCL header.
    if (messageLength < EMBER_AF_ZCL_OVERHEAD)
    {
        return EMBER_ERR_FATAL;
    }
    else if ((message[0] & ZCL_MANUFACTURER_SPECIFIC_MASK) != 0U)
    {
        if (messageLength < EMBER_AF_ZCL_MANUFACTURER_SPECIFIC_OVERHEAD)
        {
            return EMBER_ERR_FATAL;
        }
    }

    messageSentIndex = getMessageSentCallbackIndex();
    if (callback != NULL && messageSentIndex == INVALID_MESSAGE_TAG)
    {
        return EMBER_TABLE_FULL;
    }

    // The source endpoint in the APS frame MUST be valid at this point.  We use
    // it to set the appropriate outgoing network in the APS frame.
    EmberAfEndpointInfoStruct endpointInfo;
    uint8_t networkIndex = 0;
    if (emberAfGetEndpointInfoCallback(apsFrame->sourceEndpoint, &networkIndex, &endpointInfo))
    {
        //        status              = emberAfPushNetworkIndex(networkIndex);
        //        if (status != EMBER_SUCCESS)
        //        {
        //            return status;
        //        }
    }
    else
    {
        index = emberAfIndexFromEndpoint(apsFrame->sourceEndpoint);
        if (index == 0xFFFF)
        {
            return EMBER_INVALID_ENDPOINT;
        }
        //        status = emberAfPushEndpointNetworkIndex(apsFrame->sourceEndpoint);
        //        if (status != EMBER_SUCCESS)
        //        {
        //            return status;
        //        }
    }

#ifdef EMBER_AF_PLUGIN_SUB_GHZ_CLIENT
    // If the Sub-GHz client is present and currently in the "suspended" state,
    // block any outgoing message unless it comes from the Sub-GHz client itself.
    if (emberAfPluginSubGhzClientIsSendingZclMessagesSuspended() && apsFrame->clusterId != ZCL_SUB_GHZ_CLUSTER_ID)
    {
        return EMBER_TRANSMISSION_SUSPENDED;
    }
#endif

    {
        EmberAfMessageStruct messageStruct = {
            callback, apsFrame, message, destination, messageLength, broadcast,
        };
        // Called prior to fragmentation in case the mesasge does not go out over the
        // Zigbee radio, and instead goes to some other transport that does not require
        // low level ZigBee fragmentation.
        if (emberAfPreMessageSendCallback(&messageStruct, &status))
        {
            return status;
        }
    }

    // SE 1.4 requires an option to disable APS ACK and Default Response
    emAfApplyDisableDefaultResponse(&message[0]);
    emAfApplyRetryOverride(&apsFrame->options);

    if (messageLength <= EMBER_AF_MAXIMUM_SEND_PAYLOAD_LENGTH)
    {
        status = emAfSend(destination, apsFrame, messageLength, message, &messageTag, alias, sequence);
    }
    else
    {
        status = EMBER_MESSAGE_TOO_LONG;
    }

#ifdef EMBER_AF_PLUGIN_CRITICAL_MESSAGE_QUEUE
    // If this was a critical message queue entry, fire the callback
    if ((status != EMBER_SUCCESS) &&
        (callback == emberAfPluginCriticalMessageQueueEnqueueCallback || callback == emAfPluginCriticalMessageQueueRetryCallback))
    {
        callback(destination, apsFrame, messageLength, message, status);
    }
#endif // EMBER_AF_PLUGIN_CRITICAL_MESSAGE_QUEUE

    if (callback != NULL && status == EMBER_SUCCESS && messageTag != INVALID_MESSAGE_TAG &&
        messageSentIndex < EMBER_AF_MESSAGE_SENT_CALLBACK_TABLE_SIZE)
    {
        messageSentCallbacks[messageSentIndex].tag      = messageTag;
        messageSentCallbacks[messageSentIndex].callback = callback;
    }

    if (status == EMBER_OPERATION_IN_PROGRESS && apsFrame->options & EMBER_APS_OPTION_DSA_SIGN)
    {
        // We consider "in progress" signed messages as being sent successfully.
        // The stack will send the message after signing.
        status = EMBER_SUCCESS;
        // TODO: Can we actually hit this case in CHIP, or can this whole block
        // go away?
        // emAfSetCryptoOperationInProgress();
    }

    if (status == EMBER_SUCCESS)
    {
        emberAfAddToCurrentAppTasks(EMBER_AF_WAITING_FOR_DATA_ACK | EMBER_AF_WAITING_FOR_ZCL_RESPONSE);
    }

    // emberAfPopNetworkIndex();
    return status;
}

EmberStatus emberAfSendMulticastWithAliasWithCallback(GroupId multicastId, EmberApsFrame * apsFrame, uint16_t messageLength,
                                                      uint8_t * message, EmberNodeId alias, uint8_t sequence,
                                                      EmberAfMessageSentFunction callback)
{
    apsFrame->groupId      = multicastId;
    const auto destination = MessageSendDestination::MulticastWithAlias(multicastId);
    return send(destination, apsFrame, messageLength, message,
                true, // broadcast
                alias, sequence, callback);
}

EmberStatus emberAfSendMulticastWithCallback(GroupId multicastId, EmberApsFrame * apsFrame, uint16_t messageLength,
                                             uint8_t * message, EmberAfMessageSentFunction callback)
{
    apsFrame->groupId      = multicastId;
    const auto destination = MessageSendDestination::Multicast(multicastId);
    return send(destination, apsFrame, messageLength, message,
                true, // broadcast?
                0,    // alias
                0,    // sequence
                callback);
}

EmberStatus emberAfSendMulticast(GroupId multicastId, EmberApsFrame * apsFrame, uint16_t messageLength, uint8_t * message)
{
    return emberAfSendMulticastWithCallback(multicastId, apsFrame, messageLength, message, NULL);
}

EmberStatus emberAfSendMulticastToBindings(EmberApsFrame * apsFrame, uint16_t messageLength, uint8_t * message)
{
    EmberStatus status = EMBER_INVALID_BINDING_INDEX;
    uint8_t i;
    EmberBindingTableEntry binding;
    GroupId groupDest;

    if ((NULL == apsFrame) || (0 == messageLength) || (NULL == message))
    {
        return EMBER_BAD_ARGUMENT;
    }

    for (i = 0; i < EMBER_BINDING_TABLE_SIZE; i++)
    {
        status = emberGetBinding(i, &binding);
        if (status != EMBER_SUCCESS)
        {
            return status;
        }

        if (binding.type == EMBER_MULTICAST_BINDING && binding.local == apsFrame->sourceEndpoint &&
            binding.clusterId == apsFrame->clusterId)
        {
            groupDest                     = binding.groupId;
            apsFrame->groupId             = groupDest;
            apsFrame->destinationEndpoint = binding.remote;

            status = emberAfSendMulticast(groupDest, // multicast ID
                                          apsFrame, messageLength, message);

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

    return status;
}

// TODO: Figure out whether we need emberAfSendBroadcastWithCallback at all.
// EmberStatus emberAfSendBroadcastWithCallback(EmberNodeId destination, EmberApsFrame * apsFrame, uint16_t messageLength,
//                                             uint8_t * message, EmberAfMessageSentFunction callback)
//{
//    return send(EMBER_OUTGOING_BROADCAST, destination, apsFrame, messageLength, message,
//                true, // broadcast?
//                0,    // alias
//                0,    // sequence
//                callback);
//}

// TODO: Figure out whether we need emberAfSendBroadcastWithAliasWithCallback at all.
// EmberStatus emberAfSendBroadcastWithAliasWithCallback(EmberNodeId destination, EmberApsFrame * apsFrame, uint16_t messageLength,
//                                                      uint8_t * message, EmberNodeId alias, uint8_t sequence,
//                                                      EmberAfMessageSentFunction callback)
//{
//    return send(EMBER_OUTGOING_BROADCAST_WITH_ALIAS, destination, apsFrame, messageLength, message,
//                true,     // broadcast?
//                alias,    // alias
//                sequence, // sequence
//                callback);
//}

// TODO: Figure out whether we need emberAfSendBroadcast at all.
// EmberStatus emberAfSendBroadcast(EmberNodeId destination, EmberApsFrame * apsFrame, uint16_t messageLength, uint8_t * message)
//{
//    return emberAfSendBroadcastWithCallback(destination, apsFrame, messageLength, message, NULL);
//}

EmberStatus emberAfSendUnicastWithCallback(const MessageSendDestination & destination, EmberApsFrame * apsFrame,
                                           uint16_t messageLength, uint8_t * message, EmberAfMessageSentFunction callback)
{
    // The source endpoint in the APS frame MAY NOT be valid at this point if the
    // outgoing type is "via binding."
    if (destination.IsViaBinding())
    {
        // If using binding, set the endpoints based on those in the binding.  The
        // cluster in the binding is not used because bindings can be used to send
        // messages with any cluster id, not just the one set in the binding.
        EmberBindingTableEntry binding;
        // TODO: This cast should go away once
        // https://github.com/project-chip/connectedhomeip/issues/3584 is fixed.
        EmberStatus status = emberGetBinding(destination.GetBindingIndex(), &binding);
        if (status != EMBER_SUCCESS)
        {
            return status;
        }
        apsFrame->sourceEndpoint      = binding.local;
        apsFrame->destinationEndpoint = binding.remote;
    }
    return send(destination, apsFrame, messageLength, message,
                false, // broadcast?
                0,     // alias
                0,     // sequence
                callback);
}

EmberStatus emberAfSendUnicast(const MessageSendDestination & destination, EmberApsFrame * apsFrame, uint16_t messageLength,
                               uint8_t * message)
{
    return emberAfSendUnicastWithCallback(destination, apsFrame, messageLength, message, NULL);
}

EmberStatus emberAfSendUnicastToBindingsWithCallback(EmberApsFrame * apsFrame, uint16_t messageLength, uint8_t * message,
                                                     EmberAfMessageSentFunction callback)
{
    EmberStatus status = EMBER_INVALID_BINDING_INDEX;
    uint8_t i;

    for (i = 0; i < EMBER_BINDING_TABLE_SIZE; i++)
    {
        EmberBindingTableEntry binding;
        status = emberGetBinding(i, &binding);
        if (status != EMBER_SUCCESS)
        {
            return status;
        }
        if (binding.type == EMBER_UNICAST_BINDING && binding.local == apsFrame->sourceEndpoint &&
            binding.clusterId == apsFrame->clusterId)
        {
            apsFrame->destinationEndpoint            = binding.remote;
            const MessageSendDestination destination = MessageSendDestination::ViaBinding(i);
            status                                   = send(destination, apsFrame, messageLength, message,
                          false, // broadcast?
                          0,     // alias
                          0,     // sequence
                          callback);
            if (status != EMBER_SUCCESS)
            {
                return status;
            }
        }
    }

    return status;
}

EmberStatus emberAfSendUnicastToBindings(EmberApsFrame * apsFrame, uint16_t messageLength, uint8_t * message)
{
    return emberAfSendUnicastToBindingsWithCallback(apsFrame, messageLength, message, NULL);
}

EmberStatus emberAfSendInterPan(EmberPanId panId, const EmberEUI64 destinationLongId, EmberNodeId destinationShortId,
                                GroupId multicastId, ClusterId clusterId, uint16_t messageLength, uint8_t * messageBytes)
{
    EmberAfInterpanHeader header;
    memset(&header, 0, sizeof(EmberAfInterpanHeader));
    header.panId        = panId;
    header.shortAddress = destinationShortId;
    if (destinationLongId != NULL)
    {
        memmove(header.longAddress, destinationLongId, EUI64_SIZE);
        header.options |= EMBER_AF_INTERPAN_OPTION_MAC_HAS_LONG_ADDRESS;
        header.messageType = EMBER_AF_INTER_PAN_UNICAST;
    }
    else if (multicastId != 0)
    {
        header.groupId     = multicastId;
        header.messageType = EMBER_AF_INTER_PAN_MULTICAST;
    }
    else
    {
        header.messageType =
            (destinationShortId < EMBER_BROADCAST_ADDRESS ? EMBER_AF_INTER_PAN_UNICAST : EMBER_AF_INTER_PAN_BROADCAST);
    }
    header.clusterId = clusterId;
    return emberAfInterpanSendMessageCallback(&header, messageLength, messageBytes);
}

void emberAfPrintMessageData(uint8_t * data, uint16_t length)
{
#if defined EMBER_AF_PRINT_APP
    emberAfAppPrint(" payload (len %2x) [", length);
    emberAfAppPrintBuffer(data, length, true);
    emberAfAppPrintln("]");
#endif
}

void emAfPrintStatus(const char * task, EmberStatus status)
{
    if (status == EMBER_SUCCESS)
    {
        emberAfPrint(emberAfPrintActiveArea, "%p: %p", "Success", task);
    }
    else
    {
        emberAfPrint(emberAfPrintActiveArea, "%p: %p: 0x%x", "Error", task, status);
    }
}

// ******************************************************************
// Functions called by the Serial Command Line Interface (CLI)
// ******************************************************************

static void printMessage(EmberApsFrame * apsFrame, uint16_t messageLength, uint8_t * messageContents)
{
    emberAfAppPrint("Cluster: " ChipLogFormatMEI ", %d bytes,", ChipLogValueMEI(apsFrame->clusterId), messageLength);
    if (messageLength >= 3)
    {
        emberAfAppPrint(" ZCL %p Cmd ID: %d", (messageContents[0] & ZCL_CLUSTER_SPECIFIC_COMMAND ? "Cluster" : "Global"),
                        messageContents[2]);
    }
    emberAfAppPrintln("%s", "");
}

void emAfMessageSentHandler(const MessageSendDestination & destination, EmberApsFrame * apsFrame, EmberStatus status,
                            uint16_t messageLength, uint8_t * messageContents, uint8_t messageTag)
{
    EmberAfMessageSentFunction callback;
    if (status != EMBER_SUCCESS)
    {
        emberAfAppPrint("%ptx %x, ", "ERROR: ", status);
        printMessage(apsFrame, messageLength, messageContents);
    }

    callback = getMessageSentCallback(messageTag);
    invalidateMessageSentCallbackEntry(messageTag);

    emberAfRemoveFromCurrentAppTasks(EMBER_AF_WAITING_FOR_DATA_ACK);

    if (messageContents != NULL && messageContents[0] & ZCL_CLUSTER_SPECIFIC_COMMAND)
    {
        emberAfClusterMessageSentWithMfgCodeCallback(
            destination, apsFrame, messageLength, messageContents, status,
            // If the manufacturer specific flag is set
            // get read it as next part of message
            // else use null code.
            (((messageContents[0] & ZCL_MANUFACTURER_SPECIFIC_MASK) == ZCL_MANUFACTURER_SPECIFIC_MASK)
                 ? emberAfGetInt16u(messageContents, 1, messageLength)
                 : EMBER_AF_NULL_MANUFACTURER_CODE));
    }

    if (callback != NULL)
    {
        (*callback)(destination, apsFrame, messageLength, messageContents, status);
    }

#ifdef EMBER_AF_GENERATED_PLUGIN_MESSAGE_SENT_FUNCTION_CALLS
    EMBER_AF_GENERATED_PLUGIN_MESSAGE_SENT_FUNCTION_CALLS
#endif

    emberAfMessageSentCallback(destination, apsFrame, messageLength, messageContents, status);
}

#ifdef EMBER_AF_PLUGIN_FRAGMENTATION
void emAfFragmentationMessageSentHandler(const MessageSendDestination & destination, EmberApsFrame * apsFrame, uint8_t * buffer,
                                         uint16_t bufLen, EmberStatus status, uint8_t messageTag)
{
    // the fragmented message is no longer in process
    emberAfDebugPrintln("%pend.", "Fragmentation:");
    emAfMessageSentHandler(destination, apsFrame, status, bufLen, buffer, messageTag);

    // EMZIGBEE-4437: setting back the buffers to the original in case someone set
    // that to something else.
    emberAfSetExternalBuffer(appResponseData, EMBER_AF_RESPONSE_BUFFER_LEN, &appResponseLength, &emberAfResponseApsFrame);
}
#endif // EMBER_AF_PLUGIN_FRAGMENTATION

EmberStatus emAfSend(const MessageSendDestination & destination, EmberApsFrame * apsFrame, uint16_t messageLength,
                     uint8_t * message, uint8_t * messageTag, EmberNodeId alias, uint8_t sequence)
{
    // TODO: There's an impedance mismatch here in a few ways:
    // 1) The caller expects to get a messageTag out that will identify this
    // message somewhat uniquely.  Right now we just ignore that and claim an
    // invalid tag, which means message-sent callbacks don't get called.
    //
    // 2) The caller expects us to call emAfMessageSentHandler when we get an
    // ack or time out, and pass it the original contents of the message, so it
    // can invoke message-sent callbacks as needed.  But we may not have the
    // contents of the message if we've done in-place encryption since then.
    // Need to figure out whether any of this matters.
    //
    // https://github.com/project-chip/connectedhomeip/issues/2435 sort of
    // tracks this.
    *messageTag        = INVALID_MESSAGE_TAG;
    EmberStatus status = EMBER_SUCCESS;
    if (destination.IsViaBinding())
    {
        EmberBindingTableEntry binding;
        status = emberGetBinding(destination.GetBindingIndex(), &binding);
        if (status != EMBER_SUCCESS)
        {
            return status;
        }
        if (binding.type != EMBER_UNICAST_BINDING)
        {
            return EMBER_INVALID_BINDING_INDEX;
        }
        return chipSendUnicast(binding.nodeId, apsFrame, messageLength, message);
    }
    else if (destination.IsDirect())
    {
        return chipSendUnicast(destination.GetDirectNodeId(), apsFrame, messageLength, message);
    }
    else if (destination.IsViaExchange())
    {
        return chipSendUnicast(destination.GetExchangeContext(), apsFrame, messageLength, message);
    }
    else
    {
        // No implementation yet.
        return EMBER_ERR_FATAL;
    }
}
