/*
 *  Copyright (c) 2020, The OpenThread Authors.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of the copyright holder nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

#include <assert.h>
#include <string.h>

#include "bsp.h"
#include "em_cmu.h"
#include "em_emu.h"
#include "gpiointerrupt.h"
#include "hal-config.h"
#include "hal_common.h"
#include "openthread-system.h"
#include "platform-efr32.h"
#include <common/logging.hpp>
#include <openthread-core-config.h>
#include <openthread/cli.h>
#include <openthread/config.h>
#include <openthread/dataset_ftd.h>
#include <openthread/diag.h>
#include <openthread/instance.h>
#include <openthread/link.h>
#include <openthread/message.h>
#include <openthread/tasklet.h>
#include <openthread/thread.h>
#include <openthread/udp.h>
#include <openthread/platform/logging.h>

// Constants
#define MULTICAST_ADDR "ff03::1"
#define MULTICAST_PORT 123
#define RECV_PORT 234
#define SLEEPY_POLL_PERIOD_MS 5000
#define MTD_MESSAGE "mtd button"
#define FTD_MESSAGE "ftd button"

// Types
typedef struct ButtonArray
{
    GPIO_Port_TypeDef port;
    unsigned int      pin;
} ButtonArray_t;

// Prototypes
bool sleepCb(void);
void setNetworkConfiguration(otInstance *aInstance);
void handleNetifStateChanged(uint32_t aFlags, void *aContext);
void gpioInit(void (*gpioCallback)(uint8_t pin));
void buttonCallback(uint8_t pin);
void initUdp(void);
void applicationTick(void);
void mtdReceiveCallback(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);

/**
 * This function initializes the CLI app.
 *
 * @param[in]  aInstance  The OpenThread instance structure.
 *
 */
extern void otAppCliInit(otInstance *aInstance);

// Variables
static otInstance *        instance;
static otUdpSocket         sMtdSocket;
static otSockAddr          sMulticastSockAddr;
static const ButtonArray_t sButtonArray[BSP_BUTTON_COUNT] = BSP_BUTTON_INIT;
static bool                sButtonPressed                 = false;
static bool                sRxOnIdleButtonPressed         = false;
static bool                sLedOn                         = false;
static bool                sAllowDeepSleep                = false;
static bool                sTaskletsPendingSem            = true;

int main(int argc, char *argv[])
{
    otLinkModeConfig config;

    otSysInit(argc, argv);
    gpioInit(buttonCallback);

    instance = otInstanceInitSingle();
    assert(instance);

    otAppCliInit(instance);

    otLinkSetPollPeriod(instance, SLEEPY_POLL_PERIOD_MS);
    setNetworkConfiguration(instance);
    otSetStateChangedCallback(instance, handleNetifStateChanged, instance);

    config.mRxOnWhenIdle = true;
    config.mDeviceType   = 0;
    config.mNetworkData  = 0;
    otThreadSetLinkMode(instance, config);

    initUdp();
    otIp6SetEnabled(instance, true);
    otThreadSetEnabled(instance, true);
    efr32SetSleepCallback(sleepCb);

    while (!otSysPseudoResetWasRequested())
    {
        otTaskletsProcess(instance);
        otSysProcessDrivers(instance);

        applicationTick();

        // Put the EFR32 into deep sleep if callback sleepCb permits.
        efr32Sleep();
    }

    otInstanceFinalize(instance);
    return 0;
}

/*
 * Callback from efr32Sleep to indicate if it is ok to go into sleep mode.
 * This runs with interrupts disabled.
 */
bool sleepCb(void)
{
    bool allow;
    allow               = (sAllowDeepSleep && !sTaskletsPendingSem);
    sTaskletsPendingSem = false;
    return allow;
}

void otTaskletsSignalPending(otInstance *aInstance)
{
    (void)aInstance;
    sTaskletsPendingSem = true;
}

/*
 * Override default network settings, such as panid, so the devices can join a network
 */
void setNetworkConfiguration(otInstance *aInstance)
{
    static char          aNetworkName[] = "SleepyEFR32";
    otOperationalDataset aDataset;

    memset(&aDataset, 0, sizeof(otOperationalDataset));

    /*
     * Fields that can be configured in otOperationDataset to override defaults:
     *     Network Name, Mesh Local Prefix, Extended PAN ID, PAN ID, Delay Timer,
     *     Channel, Channel Mask Page 0, Network Master Key, PSKc, Security Policy
     */
    aDataset.mActiveTimestamp                      = 1;
    aDataset.mComponents.mIsActiveTimestampPresent = true;

    /* Set Channel to 15 */
    aDataset.mChannel                      = 15;
    aDataset.mComponents.mIsChannelPresent = true;

    /* Set Pan ID to 2222 */
    aDataset.mPanId                      = (otPanId)0x2222;
    aDataset.mComponents.mIsPanIdPresent = true;

    /* Set Extended Pan ID to C0DE1AB5C0DE1AB5 */
    uint8_t extPanId[OT_EXT_PAN_ID_SIZE] = {0xC0, 0xDE, 0x1A, 0xB5, 0xC0, 0xDE, 0x1A, 0xB5};
    memcpy(aDataset.mExtendedPanId.m8, extPanId, sizeof(aDataset.mExtendedPanId));
    aDataset.mComponents.mIsExtendedPanIdPresent = true;

    /* Set master key to 1234C0DE1AB51234C0DE1AB51234C0DE */
    uint8_t key[OT_MASTER_KEY_SIZE] = {0x12, 0x34, 0xC0, 0xDE, 0x1A, 0xB5, 0x12, 0x34,
                                       0xC0, 0xDE, 0x1A, 0xB5, 0x12, 0x34, 0xC0, 0xDE};
    memcpy(aDataset.mMasterKey.m8, key, sizeof(aDataset.mMasterKey));
    aDataset.mComponents.mIsMasterKeyPresent = true;

    /* Set Network Name to SleepyEFR32 */
    size_t length = strlen(aNetworkName);
    assert(length <= OT_NETWORK_NAME_MAX_SIZE);
    memcpy(aDataset.mNetworkName.m8, aNetworkName, length);
    aDataset.mComponents.mIsNetworkNamePresent = true;

    otDatasetSetActive(aInstance, &aDataset);
}

void handleNetifStateChanged(uint32_t aFlags, void *aContext)
{
    otLinkModeConfig config;

    if ((aFlags & OT_CHANGED_THREAD_ROLE) != 0)
    {
        otDeviceRole changedRole = otThreadGetDeviceRole(aContext);

        switch (changedRole)
        {
        case OT_DEVICE_ROLE_LEADER:
        case OT_DEVICE_ROLE_ROUTER:
            break;

        case OT_DEVICE_ROLE_CHILD:
            config.mRxOnWhenIdle = 0;
            config.mDeviceType   = 0;
            config.mNetworkData  = 0;
            otThreadSetLinkMode(instance, config);
            sAllowDeepSleep = false;
            break;

        case OT_DEVICE_ROLE_DETACHED:
        case OT_DEVICE_ROLE_DISABLED:
            break;
        }
    }
}

/*
 * Provide, if required an "otPlatLog()" function
 */
#if OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_APP
void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
{
    OT_UNUSED_VARIABLE(aLogLevel);
    OT_UNUSED_VARIABLE(aLogRegion);
    OT_UNUSED_VARIABLE(aFormat);

    va_list ap;
    va_start(ap, aFormat);
    otCliPlatLogv(aLogLevel, aLogRegion, aFormat, ap);
    va_end(ap);
}
#endif

void gpioInit(void (*callback)(uint8_t pin))
{
    // set up button GPIOs to input with pullups
    for (int i = 0; i < BSP_BUTTON_COUNT; i++)
    {
        GPIO_PinModeSet(sButtonArray[i].port, sButtonArray[i].pin, gpioModeInputPull, 1);
    }
    // set up interrupt based callback function on falling edge
    GPIOINT_Init();
    GPIOINT_CallbackRegister(sButtonArray[0].pin, callback);
    GPIOINT_CallbackRegister(sButtonArray[1].pin, callback);
    GPIO_IntConfig(sButtonArray[0].port, sButtonArray[0].pin, false, true, true);
    GPIO_IntConfig(sButtonArray[1].port, sButtonArray[1].pin, false, true, true);

    BSP_LedsInit();
    BSP_LedClear(0);
    BSP_LedClear(1);
}

void initUdp(void)
{
    otError    error;
    otSockAddr sockaddr;

    memset(&sMulticastSockAddr, 0, sizeof sMulticastSockAddr);
    otIp6AddressFromString(MULTICAST_ADDR, &sMulticastSockAddr.mAddress);
    sMulticastSockAddr.mPort = MULTICAST_PORT;

    memset(&sockaddr, 0, sizeof(sockaddr));
    sockaddr.mPort = RECV_PORT;

    error = otUdpOpen(instance, &sMtdSocket, mtdReceiveCallback, NULL);

    if (error != OT_ERROR_NONE)
    {
        return;
    }

    error = otUdpBind(instance, &sMtdSocket, &sockaddr);

    if (error != OT_ERROR_NONE)
    {
        otUdpClose(instance, &sMtdSocket);
        return;
    }
}

void buttonCallback(uint8_t pin)
{
    if ((pin & 0x01) == 0x01)
    {
        sButtonPressed = true;
    }
    else if ((pin & 0x01) == 0x00)
    {
        sRxOnIdleButtonPressed = true;
    }
}

void applicationTick(void)
{
    otError          error = 0;
    otMessageInfo    messageInfo;
    otMessage *      message = NULL;
    char *           payload = MTD_MESSAGE;
    otLinkModeConfig config;

    if (sRxOnIdleButtonPressed == true)
    {
        sRxOnIdleButtonPressed = false;
        sAllowDeepSleep        = !sAllowDeepSleep;
        config.mRxOnWhenIdle   = !sAllowDeepSleep;
        config.mDeviceType     = 0;
        config.mNetworkData    = 0;
        otThreadSetLinkMode(instance, config);
    }

    if (sButtonPressed == true)
    {
        sButtonPressed = false;

        memset(&messageInfo, 0, sizeof(messageInfo));
        memcpy(&messageInfo.mPeerAddr, &sMulticastSockAddr.mAddress, sizeof messageInfo.mPeerAddr);
        messageInfo.mPeerPort = sMulticastSockAddr.mPort;

        message = otUdpNewMessage(instance, NULL);

        if (message != NULL)
        {
            error = otMessageAppend(message, payload, (uint16_t)strlen(payload));

            if (error == OT_ERROR_NONE)
            {
                error = otUdpSend(instance, &sMtdSocket, message, &messageInfo);

                if (error == OT_ERROR_NONE)
                {
                    return;
                }
            }
        }

        if (message != NULL)
        {
            otMessageFree(message);
        }
    }
}

void mtdReceiveCallback(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
{
    OT_UNUSED_VARIABLE(aContext);
    OT_UNUSED_VARIABLE(aMessage);
    OT_UNUSED_VARIABLE(aMessageInfo);
    uint8_t buf[1500];
    int     length;

    length      = otMessageRead(aMessage, otMessageGetOffset(aMessage), buf, sizeof(buf) - 1);
    buf[length] = '\0';

    if (strcmp((char *)buf, FTD_MESSAGE) == 0)
    {
        sLedOn = !sLedOn;

        if (sLedOn)
        {
            BSP_LedSet(0);
        }
        else
        {
            BSP_LedClear(0);
        }
    }
}
