/**
 *
 *    Copyright (c) 2020-2021 Project CHIP Authors
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

#include "app/util/common.h"
#include <app-common/zap-generated/attribute-id.h>
#include <app-common/zap-generated/attribute-type.h>
#include <app-common/zap-generated/command-id.h>
#include <app-common/zap-generated/ids/Clusters.h>
#include <app-common/zap-generated/print-cluster.h>
#include <app/util/af-event.h>
#include <app/util/af.h>
#include <app/util/ember-compatibility-functions.h>
#include <app/util/generic-callbacks.h>

// TODO: figure out a clear path for compile-time codegen
#include <app/PluginApplicationCallbacks.h>

#ifdef EMBER_AF_PLUGIN_GROUPS_SERVER
#include <app/clusters/groups-server/groups-server.h>
#endif // EMBER_AF_PLUGIN_GROUPS_SERVER

using namespace chip;

//------------------------------------------------------------------------------
// Forward Declarations

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

#ifdef EMBER_AF_ENABLE_STATISTICS
// a variable containing the number of messages send from the utilities
// since emberAfInit was called.
uint32_t afNumPktsSent;
#endif

const EmberAfClusterName zclClusterNames[] = {
    CLUSTER_IDS_TO_NAMES            // defined in print-cluster.h
    { kInvalidClusterId, nullptr }, // terminator
};

// A pointer to the current command being processed
// This struct is allocated inside ember-compatibility-functions.cpp.
// The pointer below is set to NULL when not processing a command.
EmberAfClusterCommand * emAfCurrentCommand;

// A pointer to the global exchange manager
chip::Messaging::ExchangeManager * emAfExchangeMgr = nullptr;

// DEPRECATED.
uint8_t emberAfIncomingZclSequenceNumber = 0xFF;

// Sequence used for outgoing messages if they are
// not responses.
uint8_t emberAfSequenceNumber = 0xFF;

static uint8_t /*enum EmberAfRetryOverride*/ emberAfApsRetryOverride                      = EMBER_AF_RETRY_OVERRIDE_NONE;
static uint8_t /*enum EmberAfDisableDefaultResponse*/ emAfDisableDefaultResponse          = EMBER_AF_DISABLE_DEFAULT_RESPONSE_NONE;
static uint8_t /*enum EmberAfDisableDefaultResponse*/ emAfSavedDisableDefaultResponseVale = EMBER_AF_DISABLE_DEFAULT_RESPONSE_NONE;

// Holds the response type
uint8_t emberAfResponseType = ZCL_UTIL_RESP_NORMAL;

#ifdef EMBER_AF_GENERATED_PLUGIN_TICK_FUNCTION_DECLARATIONS
EMBER_AF_GENERATED_PLUGIN_TICK_FUNCTION_DECLARATIONS
#endif

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

// Is the device identifying?
bool emberAfIsDeviceIdentifying(EndpointId endpoint)
{
#ifdef ZCL_USING_IDENTIFY_CLUSTER_SERVER
    uint16_t identifyTime;
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, app::Clusters::Identify::Id, ZCL_IDENTIFY_TIME_ATTRIBUTE_ID,
                                                      (uint8_t *) &identifyTime, sizeof(identifyTime));
    return (status == EMBER_ZCL_STATUS_SUCCESS && 0 < identifyTime);
#else
    return false;
#endif
}

// Calculates difference. See EmberAfDifferenceType for the maximum data size
// that this function will support.
EmberAfDifferenceType emberAfGetDifference(uint8_t * pData, EmberAfDifferenceType value, uint8_t dataSize)
{
    EmberAfDifferenceType value2 = 0, diff;
    uint8_t i;

    // only support data types up to 8 bytes
    if (dataSize > sizeof(EmberAfDifferenceType))
    {
        return 0;
    }

    // get the value
    for (i = 0; i < dataSize; i++)
    {
        value2 = value2 << 8;
#if (BIGENDIAN_CPU)
        value2 += pData[i];
#else  // BIGENDIAN
        value2 += pData[dataSize - i - 1];
#endif // BIGENDIAN
    }

    if (value > value2)
    {
        diff = value - value2;
    }
    else
    {
        diff = value2 - value;
    }

    return diff;
}

// ****************************************
// Initialize Clusters
// ****************************************
void emberAfInit(chip::Messaging::ExchangeManager * exchangeMgr)
{
    uint8_t i;
#ifdef EMBER_AF_ENABLE_STATISTICS
    afNumPktsSent = 0;
#endif

    emAfExchangeMgr = exchangeMgr;

    for (i = 0; i < EMBER_SUPPORTED_NETWORKS; i++)
    {
        // FIXME: Do we need to support more than one network?
        // emberAfPushNetworkIndex(i);
        emberAfInitializeAttributes(EMBER_BROADCAST_ENDPOINT);
        // emberAfPopNetworkIndex();
    }

    MATTER_PLUGINS_INIT

    emAfCallInits();
}

void emberAfTick()
{
    // Call the AFV2-specific per-endpoint callbacks
    // Anything that defines callbacks as void *TickCallback(void) is called in
    // emAfInit(), which is a generated file
#ifdef EMBER_AF_GENERATED_PLUGIN_TICK_FUNCTION_CALLS
    EMBER_AF_GENERATED_PLUGIN_TICK_FUNCTION_CALLS
#endif
}

// Cluster init functions that don't have a cluster implementation to define
// them in.
void MatterBooleanStatePluginServerInitCallback() {}
void MatterBridgedDeviceBasicPluginServerInitCallback() {}
void MatterElectricalMeasurementPluginServerInitCallback() {}
void MatterRelativeHumidityMeasurementPluginServerInitCallback() {}
void MatterIlluminanceMeasurementPluginServerInitCallback() {}
void MatterBinaryInputBasicPluginServerInitCallback() {}
void MatterPressureMeasurementPluginServerInitCallback() {}
void MatterTemperatureMeasurementPluginServerInitCallback() {}
void MatterFlowMeasurementPluginServerInitCallback() {}
void MatterOnOffSwitchConfigurationPluginServerInitCallback() {}
void MatterThermostatUserInterfaceConfigurationPluginServerInitCallback() {}
void MatterBridgedDeviceBasicInformationPluginServerInitCallback() {}
void MatterPowerConfigurationPluginServerInitCallback() {}
void MatterPowerProfilePluginServerInitCallback() {}
void MatterPulseWidthModulationPluginServerInitCallback() {}
void MatterAlarmsPluginServerInitCallback() {}
void MatterTimePluginServerInitCallback() {}
void MatterAclPluginServerInitCallback() {}
void MatterPollControlPluginServerInitCallback() {}
void MatterUnitLocalizationPluginServerInitCallback() {}
void MatterTimeSynchronizationPluginServerInitCallback() {}
void MatterProxyValidPluginServerInitCallback() {}
void MatterProxyDiscoveryPluginServerInitCallback() {}
void MatterProxyConfigurationPluginServerInitCallback() {}
void MatterFanControlPluginServerInitCallback() {}

// ****************************************
// This function is called by the application when the stack goes down,
// such as after a leave network. This allows zcl utils to clear state
// that should not be kept when changing networks
// ****************************************
void emberAfStackDown()
{
    emberAfRegistrationAbortCallback();
}

// ****************************************
// Print out information about each cluster
// ****************************************

uint16_t emberAfFindClusterNameIndex(ClusterId cluster)
{
    static_assert(sizeof(ClusterId) == 4, "May need to adjust our index type or somehow define it in terms of cluster id type");
    uint16_t index = 0;
    while (zclClusterNames[index].id != kInvalidClusterId)
    {
        if (zclClusterNames[index].id == cluster)
        {
            return index;
        }
        index++;
    }
    return 0xFFFF;
}

// This function parses into the cluster name table, and tries to find
// the index in the table that has the right cluster id.
void emberAfDecodeAndPrintCluster(ClusterId cluster)
{
    uint16_t index = emberAfFindClusterNameIndex(cluster);
    if (index == 0xFFFF)
    {
        static_assert(sizeof(ClusterId) == 4, "Adjust the print formatting");
        emberAfPrint(emberAfPrintActiveArea, "(Unknown clus. [" ChipLogFormatMEI "])", ChipLogValueMEI(cluster));
    }
    else
    {
        emberAfPrint(emberAfPrintActiveArea, "(%p)", zclClusterNames[index].name);
    }
}

// This function makes the assumption that
// emberAfCurrentCommand will either be NULL
// when invalid, or will have a valid mfgCode
// when called.
// If it is invalid, we just return the
// EMBER_AF_NULL_MANUFACTURER_CODE, which we tend to use
// for references to the standard library.
uint16_t emberAfGetMfgCodeFromCurrentCommand()
{
    if (emberAfCurrentCommand() != nullptr)
    {
        return emberAfCurrentCommand()->mfgCode;
    }

    return EMBER_AF_NULL_MANUFACTURER_CODE;
}

// the caller to the library can set a flag to say do not respond to the
// next ZCL message passed in to the library. Passing true means disable
// the reply for the next ZCL message. Setting to false re-enables the
// reply (in the case where the app disables it and then doesnt send a
// message that gets parsed).
void emberAfSetNoReplyForNextMessage(bool set)
{
    if (set)
    {
        emberAfResponseType |= ZCL_UTIL_RESP_NONE;
    }
    else
    {
        emberAfResponseType = static_cast<uint8_t>(emberAfResponseType & ~ZCL_UTIL_RESP_NONE);
    }
}

void emberAfSetRetryOverride(EmberAfRetryOverride value)
{
    emberAfApsRetryOverride = value;
}

EmberAfRetryOverride emberAfGetRetryOverride()
{
    return (EmberAfRetryOverride) emberAfApsRetryOverride;
}

void emAfApplyRetryOverride(EmberApsOption * options)
{
    if (options == nullptr)
    {
        return;
    }
    if (emberAfApsRetryOverride == EMBER_AF_RETRY_OVERRIDE_SET)
    {
        *options |= EMBER_APS_OPTION_RETRY;
    }
    else if (emberAfApsRetryOverride == EMBER_AF_RETRY_OVERRIDE_UNSET)
    {
        *options = static_cast<EmberApsOption>(*options & ~EMBER_APS_OPTION_RETRY);
    }
    else
    {
        // MISRA requires ..else if.. to have terminating else.
    }
}

void emberAfSetDisableDefaultResponse(EmberAfDisableDefaultResponse value)
{
    emAfDisableDefaultResponse = value;
    if (value != EMBER_AF_DISABLE_DEFAULT_RESPONSE_ONE_SHOT)
    {
        emAfSavedDisableDefaultResponseVale = value;
    }
}

EmberAfDisableDefaultResponse emberAfGetDisableDefaultResponse()
{
    return (EmberAfDisableDefaultResponse) emAfDisableDefaultResponse;
}

void emAfApplyDisableDefaultResponse(uint8_t * frame_control)
{
    if (frame_control == nullptr)
    {
        return;
    }
    if (emAfDisableDefaultResponse == EMBER_AF_DISABLE_DEFAULT_RESPONSE_ONE_SHOT)
    {
        emAfDisableDefaultResponse = emAfSavedDisableDefaultResponseVale;
        *frame_control |= ZCL_DISABLE_DEFAULT_RESPONSE_MASK;
    }
    else if (emAfDisableDefaultResponse == EMBER_AF_DISABLE_DEFAULT_RESPONSE_PERMANENT)
    {
        *frame_control |= ZCL_DISABLE_DEFAULT_RESPONSE_MASK;
    }
    else
    {
        // MISRA requires ..else if.. to have terminating else.
    }
}

EmberStatus emberAfSendImmediateDefaultResponse(EmberAfStatus status)
{
    return emberAfSendDefaultResponse(emberAfCurrentCommand(), status);
}

EmberStatus emberAfSendDefaultResponse(const EmberAfClusterCommand * cmd, EmberAfStatus status)
{
    // Default Response commands are only sent in response to unicast commands.
    if (cmd->type != EMBER_INCOMING_UNICAST && cmd->type != EMBER_INCOMING_UNICAST_REPLY)
    {
        return EMBER_SUCCESS;
    }

    if (!chip::app::Compatibility::IMEmberAfSendDefaultResponseWithCallback(status))
    {
        // Caller is not responding to anything!
        return EMBER_ERR_FATAL;
    }

    return EMBER_SUCCESS;
}

void emberAfCopyInt16u(uint8_t * data, uint16_t index, uint16_t x)
{
    data[index]     = (uint8_t)(((x)) & 0xFF);
    data[index + 1] = (uint8_t)(((x) >> 8) & 0xFF);
}

void emberAfCopyInt24u(uint8_t * data, uint16_t index, uint32_t x)
{
    data[index]     = (uint8_t)(((x)) & 0xFF);
    data[index + 1] = (uint8_t)(((x) >> 8) & 0xFF);
    data[index + 2] = (uint8_t)(((x) >> 16) & 0xFF);
}

void emberAfCopyInt32u(uint8_t * data, uint16_t index, uint32_t x)
{
    data[index]     = (uint8_t)(((x)) & 0xFF);
    data[index + 1] = (uint8_t)(((x) >> 8) & 0xFF);
    data[index + 2] = (uint8_t)(((x) >> 16) & 0xFF);
    data[index + 3] = (uint8_t)(((x) >> 24) & 0xFF);
}

void emberAfCopyString(uint8_t * dest, const uint8_t * src, size_t size)
{
    if (src == nullptr)
    {
        dest[0] = 0; // Zero out the length of string
    }
    else if (src[0] == 0xFF)
    {
        dest[0] = src[0];
    }
    else
    {
        uint8_t length = emberAfStringLength(src);
        if (size < length)
        {
            // Since we have checked that size < length, size must be able to fit into the type of length.
            length = static_cast<decltype(length)>(size);
        }
        memmove(dest + 1, src + 1, length);
        dest[0] = length;
    }
}

void emberAfCopyLongString(uint8_t * dest, const uint8_t * src, size_t size)
{
    if (src == nullptr)
    {
        dest[0] = dest[1] = 0; // Zero out the length of string
    }
    else if ((src[0] == 0xFF) && (src[1] == 0xFF))
    {
        dest[0] = 0xFF;
        dest[1] = 0xFF;
    }
    else
    {
        uint16_t length = emberAfLongStringLength(src);
        if (size < length)
        {
            // Since we have checked that size < length, size must be able to fit into the type of length.
            length = static_cast<decltype(length)>(size);
        }
        memmove(dest + 2, src + 2, length);
        dest[0] = EMBER_LOW_BYTE(length);
        dest[1] = EMBER_HIGH_BYTE(length);
    }
}

#if (BIGENDIAN_CPU)
#define EM_BIG_ENDIAN true
#else
#define EM_BIG_ENDIAN false
#endif

// You can pass in val1 as NULL, which will assume that it is
// pointing to an array of all zeroes. This is used so that
// default value of NULL is treated as all zeroes.
int8_t emberAfCompareValues(const uint8_t * val1, const uint8_t * val2, uint16_t len, bool signedNumber)
{
    if (len == 0)
    {
        // no length means nothing to compare.  Shouldn't even happen, since len is sizeof(some-integer-type).
        return 0;
    }

    if (signedNumber)
    { // signed number comparison
        if (len <= 4)
        { // only number with 32-bits or less is supported
            int32_t accum1 = 0x0;
            int32_t accum2 = 0x0;
            int32_t all1s  = -1;

            for (uint16_t i = 0; i < len; i++)
            {
                uint8_t j = (val1 == nullptr ? 0 : (EM_BIG_ENDIAN ? val1[i] : val1[(len - 1) - i]));
                accum1 |= j << (8 * (len - 1 - i));

                uint8_t k = (EM_BIG_ENDIAN ? val2[i] : val2[(len - 1) - i]);
                accum2 |= k << (8 * (len - 1 - i));
            }

            // sign extending, no need for 32-bits numbers
            if (len < 4)
            {
                if ((accum1 & (1 << (8 * len - 1))) != 0)
                { // check sign
                    accum1 |= all1s - ((1 << (len * 8)) - 1);
                }
                if ((accum2 & (1 << (8 * len - 1))) != 0)
                { // check sign
                    accum2 |= all1s - ((1 << (len * 8)) - 1);
                }
            }

            if (accum1 > accum2)
            {
                return 1;
            }
            if (accum1 < accum2)
            {
                return -1;
            }

            return 0;
        }

        // not supported
        return 0;
    }

    // regular unsigned number comparison
    for (uint16_t i = 0; i < len; i++)
    {
        uint8_t j = (val1 == nullptr ? 0 : (EM_BIG_ENDIAN ? val1[i] : val1[(len - 1) - i]));
        uint8_t k = (EM_BIG_ENDIAN ? val2[i] : val2[(len - 1) - i]);

        if (j > k)
        {
            return 1;
        }
        if (k > j)
        {
            return -1;
        }
    }
    return 0;
}

#if 0
// Moving to time-util.c
int8_t emberAfCompareDates(EmberAfDate* date1, EmberAfDate* date2)
{
  uint32_t val1 = emberAfEncodeDate(date1);
  uint32_t val2 = emberAfEncodeDate(date2);
  return (val1 == val2) ? 0 : ((val1 < val2) ? -1 : 1);
}
#endif

// Zigbee spec says types between signed 8 bit and signed 64 bit
bool emberAfIsTypeSigned(EmberAfAttributeType dataType)
{
    return (dataType >= ZCL_INT8S_ATTRIBUTE_TYPE && dataType <= ZCL_INT64S_ATTRIBUTE_TYPE);
}

uint8_t emberAfAppendCharacters(uint8_t * zclString, uint8_t zclStringMaxLen, const uint8_t * appendingChars,
                                uint8_t appendingCharsLen)
{
    uint8_t freeChars;
    uint8_t curLen;
    uint8_t charsToWrite;

    if ((zclString == nullptr) || (zclStringMaxLen == 0) || (appendingChars == nullptr) || (appendingCharsLen == 0))
    {
        return 0;
    }

    curLen = emberAfStringLength(zclString);

    if ((zclString[0] == 0xFF) || (curLen >= zclStringMaxLen))
    {
        return 0;
    }

    freeChars    = static_cast<uint8_t>(zclStringMaxLen - curLen);
    charsToWrite = (freeChars > appendingCharsLen) ? appendingCharsLen : freeChars;

    memcpy(&zclString[1 + curLen], // 1 is to account for zcl's length byte
           appendingChars, charsToWrite);
    // Cast is safe, because the sum can't be bigger than zclStringMaxLen.
    zclString[0] = static_cast<uint8_t>(curLen + charsToWrite);
    return charsToWrite;
}

/*
   On each page, first channel maps to channel number zero and so on.
   Example:
   page    Band      Rage of 90 channels    Per page channel mapping
   28     863 MHz        0-26                    0-26
   29     863 MHz        27-34,62                0-8 (Here 7th channel maps to 34 and 8th to 62)
   30     863 MHz        35 - 61                 0-26
   31     915            0-26                    0-26

 */
EmberStatus emAfValidateChannelPages(uint8_t page, uint8_t channel)
{
    switch (page)
    {
    case 0:
        if (!((channel <= EMBER_MAX_802_15_4_CHANNEL_NUMBER) &&
              ((EMBER_MIN_802_15_4_CHANNEL_NUMBER == 0) || (channel >= EMBER_MIN_802_15_4_CHANNEL_NUMBER))))
        {
            return EMBER_PHY_INVALID_CHANNEL;
        }
        break;
    case 28:
    case 30:
    case 31:
        if (channel > EMBER_MAX_SUBGHZ_CHANNEL_NUMBER_ON_PAGES_28_30_31)
        {
            return EMBER_PHY_INVALID_CHANNEL;
        }
        break;
    case 29:
        if (channel > EMBER_MAX_SUBGHZ_CHANNEL_NUMBER_ON_PAGE_29)
        {
            return EMBER_PHY_INVALID_CHANNEL;
        }
        break;
    default:
        return EMBER_PHY_INVALID_CHANNEL;
        break;
    }
    return EMBER_SUCCESS;
}

void slabAssert(const char * file, int line)
{
    (void) file; // Unused parameter
    (void) line; // Unused parameter
    // Wait forever until the watchdog fires
    while (true)
    {
    }
}

#define ENCODED_8BIT_CHANPG_PAGE_MASK 0xE0         // top 3 bits
#define ENCODED_8BIT_CHANPG_PAGE_MASK_PAGE_0 0x00  // 0b000xxxxx
#define ENCODED_8BIT_CHANPG_PAGE_MASK_PAGE_28 0x80 // 0b100xxxxx
#define ENCODED_8BIT_CHANPG_PAGE_MASK_PAGE_29 0xA0 // 0b101xxxxx
#define ENCODED_8BIT_CHANPG_PAGE_MASK_PAGE_30 0xC0 // 0b110xxxxx
#define ENCODED_8BIT_CHANPG_PAGE_MASK_PAGE_31 0xE0 // 0b111xxxxx

#define ENCODED_8BIT_CHANPG_CHANNEL_MASK 0x1F // bottom 5 bits

uint8_t emberAfGetPageFrom8bitEncodedChanPg(uint8_t chanPg)
{
    switch (chanPg & ENCODED_8BIT_CHANPG_PAGE_MASK)
    {
    case ENCODED_8BIT_CHANPG_PAGE_MASK_PAGE_0:
        return 0;
    case ENCODED_8BIT_CHANPG_PAGE_MASK_PAGE_28:
        return 28;
    case ENCODED_8BIT_CHANPG_PAGE_MASK_PAGE_29:
        return 29;
    case ENCODED_8BIT_CHANPG_PAGE_MASK_PAGE_30:
        return 30;
    case ENCODED_8BIT_CHANPG_PAGE_MASK_PAGE_31:
        return 31;
    default:
        return 0xFF;
    }
}

uint8_t emberAfGetChannelFrom8bitEncodedChanPg(uint8_t chanPg)
{
    return chanPg & ENCODED_8BIT_CHANPG_CHANNEL_MASK;
}

uint8_t emberAfMake8bitEncodedChanPg(uint8_t page, uint8_t channel)
{
    if (emAfValidateChannelPages(page, channel) != EMBER_SUCCESS)
    {
        return 0xFF;
    }

    switch (page)
    {
    case 28:
        return channel | ENCODED_8BIT_CHANPG_PAGE_MASK_PAGE_28;
    case 29:
        return channel | ENCODED_8BIT_CHANPG_PAGE_MASK_PAGE_29;
    case 30:
        return channel | ENCODED_8BIT_CHANPG_PAGE_MASK_PAGE_30;
    case 31:
        return channel | ENCODED_8BIT_CHANPG_PAGE_MASK_PAGE_31;
    default:
        // Strictly speaking, we only need case 0 here, but MISRA in its infinite
        // wisdom requires a default case. Since we have validated the arguments
        // already, and 0 is the only remaining case, we simply treat the default
        // as case 0 to make MISRA happy.
        return channel | ENCODED_8BIT_CHANPG_PAGE_MASK_PAGE_0;
    }
}

bool emberAfContainsAttribute(chip::EndpointId endpoint, chip::ClusterId clusterId, chip::AttributeId attributeId)
{
    return (emberAfGetServerAttributeIndexByAttributeId(endpoint, clusterId, attributeId) != UINT16_MAX);
}

bool emberAfIsKnownVolatileAttribute(chip::EndpointId endpoint, chip::ClusterId clusterId, chip::AttributeId attributeId)
{
    const EmberAfAttributeMetadata * metadata = emberAfLocateAttributeMetadata(endpoint, clusterId, attributeId);

    if (metadata == nullptr)
    {
        return false;
    }

    return !metadata->IsAutomaticallyPersisted() && !metadata->IsExternal();
}

chip::Messaging::ExchangeManager * chip::ExchangeManager()
{
    return emAfExchangeMgr;
}
