/*
 *  Copyright (c) 2016, 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.
 */

/**
 * @file radio.cpp
 * Platform abstraction for radio communication.
 */

#include <openthread/platform/alarm-milli.h>
#include <openthread/platform/radio.h>

#include <string.h>

#include "platform-da15000.h"
#include "common/logging.hpp"
#include "utils/code_utils.h"

#include "ad_ftdf.h"
#include "ad_ftdf_phy_api.h"
#include "hw_otpc.h"
#include "hw_rf.h"
#include "internal.h"

// clang-format off
#define FACTORY_TEST_TIMESTAMP      (0x7F8EA08) // Register holds a timestamp of facotry test of a chip
#define FACTORY_TESTER_ID           (0x7F8EA0C) // Register holds test machine ID used for factory test

#define RADIO_DEFAULT_CHANNEL       (11)
#define RADIO_EUI64_TABLE_SIZE      (8)
#define RADIO_FRAMES_BUFFER_SIZE    (32)
// clang-format on

enum
{
    DA15000_RECEIVE_SENSITIVITY = -100, // dBm
};

static ftdf_dbm      sRssiReal = -100; // Initialize with the worst power
static otInstance *  sThreadInstance;
static otRadioState  sRadioState = OT_RADIO_STATE_DISABLED;
static otRadioFrame  sReceiveFrame[RADIO_FRAMES_BUFFER_SIZE];
static otRadioFrame *sReceiveFrameAck;
static otRadioFrame  sTransmitFrame;
static otError       sTransmitStatus;
static bool          sAckFrame          = false;
static bool          sDropFrame         = false;
static bool          sRadioPromiscuous  = false;
static bool          sTransmitDoneFrame = false;
static uint8_t       sChannel           = RADIO_DEFAULT_CHANNEL;
static uint8_t       sEnableRX          = 0;
static int8_t        sTxPower           = OPENTHREAD_CONFIG_DEFAULT_TRANSMIT_POWER;
static uint8_t       sReadFrame         = 0;
static uint8_t       sWriteFrame        = 0;
static uint32_t      sSleepInitDelay    = 0;

static uint8_t sEui64[RADIO_EUI64_TABLE_SIZE];
static uint8_t sReceivePsdu[RADIO_FRAMES_BUFFER_SIZE][OT_RADIO_FRAME_MAX_SIZE];
static uint8_t sTransmitPsdu[OT_RADIO_FRAME_MAX_SIZE];

static void da15000OtpRead(void)
{
    hw_otpc_init();    // Start clock.
    hw_otpc_disable(); // Make sure it is in standby mode.
    hw_otpc_init();    // Restart clock.
    hw_otpc_manual_read_on(false);

    __DMB();
    uint32_t *factoryTestTimeStamp = (uint32_t *)FACTORY_TEST_TIMESTAMP;
    uint32_t *factoryTestId        = (uint32_t *)FACTORY_TESTER_ID;
    __DMB();

    sEui64[0] = 0x80; // 80-EA-CA is for Dialog Semiconductor
    sEui64[1] = 0xEA;
    sEui64[2] = 0xCA;
    sEui64[3] = (*factoryTestId >> 8) & 0xff;
    sEui64[4] = (*factoryTestTimeStamp >> 24) & 0xff;
    sEui64[5] = (*factoryTestTimeStamp >> 16) & 0xff;
    sEui64[6] = (*factoryTestTimeStamp >> 8) & 0xff;
    sEui64[7] = *factoryTestTimeStamp & 0xff;

    hw_otpc_manual_read_off();
    hw_otpc_disable();
}

void da15000RadioInit(void)
{
    uint16_t ptr;

    /* Wake up power domains */
    REG_CLR_BIT(CRG_TOP, PMU_CTRL_REG, FTDF_SLEEP);

    while (REG_GETF(CRG_TOP, SYS_STAT_REG, FTDF_IS_UP) == 0x0)
        ;

    REG_CLR_BIT(CRG_TOP, PMU_CTRL_REG, RADIO_SLEEP);

    while (REG_GETF(CRG_TOP, SYS_STAT_REG, RAD_IS_UP) == 0x0)
        ;

    REG_SETF(CRG_TOP, CLK_RADIO_REG, FTDF_MAC_ENABLE, 1);
    REG_SETF(CRG_TOP, CLK_RADIO_REG, FTDF_MAC_DIV, 0);

    hw_rf_poweron();
    hw_rf_system_init();

    ad_ftdf_init_phy_api();

    da15000OtpRead();

    sChannel             = RADIO_DEFAULT_CHANNEL;
    sTransmitFrame.mPsdu = sTransmitPsdu;

    for (ptr = 0; ptr != RADIO_FRAMES_BUFFER_SIZE; ptr++)
    {
        sReceiveFrame[ptr].mPsdu = &sReceivePsdu[ptr][0];
    }

    otLogInfoPlat(sThreadInstance, "Radio initialized", NULL);
}

void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64)
{
    (void)aInstance;

    memcpy(aIeeeEui64, sEui64, RADIO_EUI64_TABLE_SIZE);
}

void otPlatRadioSetPanId(otInstance *aInstance, uint16_t aPanid)
{
    otLogInfoPlat(aInstance, "Set PanId: %X", aPanid);

    ftdf_set_value(FTDF_PIB_PAN_ID, &aPanid);
}

void otPlatRadioSetExtendedAddress(otInstance *aInstance, const otExtAddress *aAddress)
{
    otLogInfoPlat(aInstance, "Set Extended Address: %X%X%X%X%X%X%X%X", aAddress->m8[7], aAddress->m8[6],
                  aAddress->m8[5], aAddress->m8[4], aAddress->m8[3], aAddress->m8[2], aAddress->m8[1], aAddress->m8[0]);

    ftdf_set_value(FTDF_PIB_EXTENDED_ADDRESS, aAddress->m8);
}

void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t aAddress)
{
    otLogInfoPlat(aInstance, "Set Short Address: %X", aAddress);

    ftdf_set_value(FTDF_PIB_SHORT_ADDRESS, &aAddress);
}

otError otPlatRadioEnable(otInstance *aInstance)
{
    ftdf_bitmap32_t options;
    otError         error = OT_ERROR_NONE;
    uint8_t         modeCCA;

    otEXPECT_ACTION(sRadioState == OT_RADIO_STATE_DISABLED, error = OT_ERROR_INVALID_STATE);

    sThreadInstance = aInstance;

    sEnableRX = 1;
    ftdf_set_value(FTDF_PIB_RX_ON_WHEN_IDLE, &sEnableRX);

    ftdf_set_value(FTDF_PIB_CURRENT_CHANNEL, &sChannel);

    modeCCA = FTDF_CCA_MODE_2;
    ftdf_set_value(FTDF_PIB_CCA_MODE, &modeCCA);

    options = FTDF_TRANSPARENT_ENABLE_FCS_GENERATION;
    options |= FTDF_TRANSPARENT_WAIT_FOR_ACK;
    options |= FTDF_TRANSPARENT_AUTO_ACK;

    ftdf_enable_transparent_mode(FTDF_TRUE, options);
    otPlatRadioSetPromiscuous(aInstance, false);

    otLogDebgPlat(aInstance, "Radio state: OT_RADIO_STATE_SLEEP", NULL);
    sRadioState = OT_RADIO_STATE_SLEEP;

exit:
    return error;
}

otError otPlatRadioDisable(otInstance *aInstance)
{
    sEnableRX = 0;
    ftdf_set_value(FTDF_PIB_RX_ON_WHEN_IDLE, &sEnableRX);
    ad_ftdf_sleep_when_possible(FTDF_TRUE);

    ftdf_fppr_reset();

    otLogDebgPlat(aInstance, "Radio state: OT_RADIO_STATE_DISABLED", NULL);
    sRadioState = OT_RADIO_STATE_DISABLED;

    return OT_ERROR_NONE;
}

bool otPlatRadioIsEnabled(otInstance *aInstance)
{
    (void)aInstance;

    return (sRadioState != OT_RADIO_STATE_DISABLED);
}

otError otPlatRadioSleep(otInstance *aInstance)
{
    otError error = OT_ERROR_NONE;

    if (sRadioState == OT_RADIO_STATE_RECEIVE && sSleepInitDelay == 0)
    {
        sSleepInitDelay = otPlatAlarmMilliGetNow();
        return OT_ERROR_NONE;
    }
    else if ((otPlatAlarmMilliGetNow() - sSleepInitDelay) < dg_configINITIAL_SLEEP_DELAY_TIME)
    {
        return OT_ERROR_NONE;
    }

    otEXPECT_ACTION(sRadioState == OT_RADIO_STATE_RECEIVE, error = OT_ERROR_INVALID_STATE);

    otLogDebgPlat(aInstance, "Radio state: OT_RADIO_STATE_SLEEP", NULL);
    sRadioState = OT_RADIO_STATE_SLEEP;

    sEnableRX = 0;
    ftdf_set_value(FTDF_PIB_RX_ON_WHEN_IDLE, &sEnableRX);
    ad_ftdf_sleep_when_possible(FTDF_TRUE);

exit:
    return error;
}

otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
{
    otError error = OT_ERROR_NONE;

    otEXPECT_ACTION(sRadioState != OT_RADIO_STATE_DISABLED, error = OT_ERROR_INVALID_STATE);

    ad_ftdf_wake_up();

    sEnableRX = 0;
    ftdf_set_value(FTDF_PIB_RX_ON_WHEN_IDLE, &sEnableRX);

    sChannel = aChannel;
    ftdf_set_value(FTDF_PIB_CURRENT_CHANNEL, &aChannel);

    sEnableRX = 1;
    ftdf_set_value(FTDF_PIB_RX_ON_WHEN_IDLE, &sEnableRX);

    otLogDebgPlat(aInstance, "Radio state: OT_RADIO_STATE_RECEIVE", NULL);
    sRadioState = OT_RADIO_STATE_RECEIVE;

exit:
    return error;
}

void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable)
{
    (void)aInstance;
    (void)aEnable;
}

otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
{
    otError error = OT_ERROR_NONE;
    uint8_t entry;
    uint8_t entryIdx;

    // check if address already stored
    otEXPECT(!ftdf_fppr_lookup_short_address(aShortAddress, &entry, &entryIdx));

    otEXPECT_ACTION(ftdf_fppr_get_free_short_address(&entry, &entryIdx), error = OT_ERROR_NO_BUFS);

    otLogDebgPlat(aInstance, "Add ShortAddress entry: %d", entry);

    ftdf_fppr_set_short_address(entry, entryIdx, aShortAddress);
    ftdf_fppr_set_short_address_valid(entry, entryIdx, FTDF_TRUE);

exit:
    return error;
}

otError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
{
    otError            error = OT_ERROR_NONE;
    uint8_t            entry;
    ftdf_ext_address_t addr;
    uint32_t           addrL;
    uint64_t           addrH;

    addrL =
        (aExtAddress->m8[3] << 24) | (aExtAddress->m8[2] << 16) | (aExtAddress->m8[1] << 8) | (aExtAddress->m8[0] << 0);
    addrH =
        (aExtAddress->m8[7] << 24) | (aExtAddress->m8[6] << 16) | (aExtAddress->m8[5] << 8) | (aExtAddress->m8[4] << 0);
    addr = addrL | (addrH << 32);

    // check if address already stored
    otEXPECT(!ftdf_fppr_lookup_ext_address(addr, &entry));

    otEXPECT_ACTION(ftdf_fppr_get_free_ext_address(&entry), error = OT_ERROR_NO_BUFS);

    otLogDebgPlat(aInstance, "Add ExtAddress entry: %d", entry);

    ftdf_fppr_set_ext_address(entry, addr);
    ftdf_fppr_set_ext_address_valid(entry, FTDF_TRUE);

exit:
    return error;
}

otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
{
    otError error = OT_ERROR_NONE;
    uint8_t entry;
    uint8_t entryIdx;

    otEXPECT_ACTION(ftdf_fppr_lookup_short_address(aShortAddress, &entry, &entryIdx), error = OT_ERROR_NO_ADDRESS);

    otLogDebgPlat(aInstance, "Clear ShortAddress entry: %d", entry);

    ftdf_fppr_set_short_address(entry, entryIdx, 0);
    ftdf_fppr_set_short_address_valid(entry, entryIdx, FTDF_FALSE);

exit:
    return error;
}

otError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
{
    otError            error = OT_ERROR_NONE;
    uint8_t            entry;
    ftdf_ext_address_t addr;
    uint32_t           addrL;
    uint64_t           addrH;

    addrL =
        (aExtAddress->m8[3] << 24) | (aExtAddress->m8[2] << 16) | (aExtAddress->m8[1] << 8) | (aExtAddress->m8[0] << 0);
    addrH =
        (aExtAddress->m8[7] << 24) | (aExtAddress->m8[6] << 16) | (aExtAddress->m8[5] << 8) | (aExtAddress->m8[4] << 0);
    addr = addrL | (addrH << 32);

    otEXPECT_ACTION(ftdf_fppr_lookup_ext_address(addr, &entry), error = OT_ERROR_NO_ADDRESS);

    otLogDebgPlat(aInstance, "Clear ExtAddress entry: %d", entry);

    ftdf_fppr_set_ext_address(entry, 0);
    ftdf_fppr_set_ext_address_valid(entry, FTDF_FALSE);

exit:
    return error;
}

void otPlatRadioClearSrcMatchShortEntries(otInstance *aInstance)
{
    uint8_t i, j;

    otLogDebgPlat(aInstance, "Clear ShortAddress entries", NULL);

    for (i = 0; i < FTDF_FPPR_TABLE_ENTRIES; i++)
    {
        for (j = 0; j < 4; j++)
        {
            if (ftdf_fppr_get_short_address_valid(i, j))
            {
                ftdf_fppr_set_short_address_valid(i, j, FTDF_FALSE);
            }
        }
    }
}

void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance)
{
    uint8_t i;

    otLogDebgPlat(aInstance, "Clear ExtAddress entries", NULL);

    for (i = 0; i < FTDF_FPPR_TABLE_ENTRIES; i++)
    {
        if (ftdf_fppr_get_ext_address_valid(i))
        {
            ftdf_fppr_set_ext_address_valid(i, FTDF_FALSE);
        }
    }
}

otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
{
    (void)aInstance;

    return &sTransmitFrame;
}

otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame)
{
    otError error = OT_ERROR_NONE;

    otEXPECT_ACTION(sRadioState != OT_RADIO_STATE_DISABLED, error = OT_ERROR_INVALID_STATE);

    otLogDebgPlat(aInstance, "Radio start transmit: %d bytes on channel: %d", aFrame->mLength, aFrame->mChannel);

    ad_ftdf_send_frame_simple(aFrame->mLength, aFrame->mPsdu, aFrame->mChannel, 0, FTDF_TRUE);

    otLogDebgPlat(aInstance, "Radio state: OT_RADIO_STATE_TRANSMIT", NULL);
    sRadioState = OT_RADIO_STATE_TRANSMIT;

    otPlatRadioTxStarted(aInstance, aFrame);

exit:
    return error;
}

int8_t otPlatRadioGetRssi(otInstance *aInstance)
{
    (void)aInstance;

    return sRssiReal;
}

otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
{
    (void)aInstance;

    return OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_TRANSMIT_RETRIES | OT_RADIO_CAPS_CSMA_BACKOFF;
}

bool otPlatRadioGetPromiscuous(otInstance *aInstance)
{
    (void)aInstance;

    return sRadioPromiscuous;
}

void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable)
{
    otLogInfoPlat(aInstance, "Set Promiscuous: %d", aEnable ? 1 : 0);

    ftdf_set_value(FTDF_PIB_PROMISCUOUS_MODE, &aEnable);
    sRadioPromiscuous = aEnable;
}

otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration)
{
    (void)aInstance;
    (void)aScanChannel;
    (void)aScanDuration;

    return OT_ERROR_NOT_IMPLEMENTED;
}

otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower)
{
    otError error = OT_ERROR_NONE;
    (void)aInstance;

    otEXPECT_ACTION(aPower != NULL, error = OT_ERROR_INVALID_ARGS);
    *aPower = sTxPower;

exit:
    return error;
}

otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower)
{
    otLogInfoPlat(aInstance, "Set DefaultTxPower: %d", aPower);

    sTxPower = aPower;
    ftdf_set_value(FTDF_PIB_TX_POWER, &aPower);

    return OT_ERROR_NONE;
}

void da15000RadioProcess(otInstance *aInstance)
{
    ftdf_frame_header_t frameHeader;

    if (sReadFrame != sWriteFrame)
    {
        ftdf_get_frame_header(sReceiveFrame[sReadFrame].mPsdu, &frameHeader);

        otLogDebgPlat(aInstance, "Radio received: %d bytes", sReceiveFrame[sReadFrame].mLength);

        if (frameHeader.frame_type == FTDF_ACKNOWLEDGEMENT_FRAME)
        {
            sReceiveFrameAck = &sReceiveFrame[sReadFrame];
            sAckFrame        = true;
        }

        otPlatRadioReceiveDone(sThreadInstance, &sReceiveFrame[sReadFrame], OT_ERROR_NONE);

        sReadFrame = (sReadFrame + 1) % RADIO_FRAMES_BUFFER_SIZE;
        sDropFrame = false;
    }

    if (sTransmitDoneFrame)
    {
        otLogDebgPlat(aInstance, "Radio transmit status: %s", otThreadErrorToString(sTransmitStatus));

        ftdf_get_frame_header(sTransmitFrame.mPsdu, &frameHeader);

        if ((frameHeader.options & FTDF_OPT_ACK_REQUESTED) == 0 || sTransmitStatus != OT_ERROR_NONE)
        {
            sRadioState = OT_RADIO_STATE_RECEIVE;
            otPlatRadioTxDone(sThreadInstance, &sTransmitFrame, NULL, sTransmitStatus);
        }
        else
        {
            otEXPECT(sAckFrame);
            sRadioState = OT_RADIO_STATE_RECEIVE;
            otPlatRadioTxDone(sThreadInstance, &sTransmitFrame, sReceiveFrameAck, sTransmitStatus);
            sAckFrame = false;
        }

        sTransmitDoneFrame = false;

        otLogDebgPlat(aInstance, "Radio state: OT_RADIO_STATE_RECEIVE", NULL);
    }

exit:
    return;
}

void ftdf_send_frame_transparent_confirm(void *handle, ftdf_bitmap32_t status)
{
    (void)handle;

    switch (status)
    {
    case FTDF_TRANSPARENT_SEND_SUCCESSFUL:
        sTransmitStatus = OT_ERROR_NONE;
        break;

    case FTDF_TRANSPARENT_CSMACA_FAILURE:
        sTransmitStatus = OT_ERROR_CHANNEL_ACCESS_FAILURE;
        break;

    case FTDF_TRANSPARENT_NO_ACK:
        sTransmitStatus = OT_ERROR_NO_ACK;
        break;

    default:
        sTransmitStatus = OT_ERROR_ABORT;
        break;
    }

    sTransmitDoneFrame = true;
}

static void radioRssiCalc(ftdf_link_quality_t link_quality)
{
    sRssiReal = (ftdf_dbm)((0.5239 * (float)link_quality) - 114.8604);
}

void ftdf_rcv_frame_transparent(ftdf_data_length_t  frame_length,
                                ftdf_octet_t *      frame,
                                ftdf_bitmap32_t     status,
                                ftdf_link_quality_t link_quality)
{
    otEXPECT(frame_length <= OT_RADIO_FRAME_MAX_SIZE);

    otEXPECT(sRadioState != OT_RADIO_STATE_DISABLED);

    otEXPECT(!sDropFrame);

    if (status == FTDF_TRANSPARENT_RCV_SUCCESSFUL)
    {
        radioRssiCalc(link_quality);

        if (otPlatRadioGetPromiscuous(sThreadInstance))
        {
            // Timestamp
            sReceiveFrame[sWriteFrame].mInfo.mRxInfo.mMsec = otPlatAlarmMilliGetNow();
            sReceiveFrame[sWriteFrame].mInfo.mRxInfo.mUsec = 0; // Don't support microsecond timer for now.
        }

        sReceiveFrame[sWriteFrame].mChannel            = sChannel;
        sReceiveFrame[sWriteFrame].mLength             = frame_length;
        sReceiveFrame[sWriteFrame].mInfo.mRxInfo.mLqi  = OT_RADIO_LQI_NONE;
        sReceiveFrame[sWriteFrame].mInfo.mRxInfo.mRssi = otPlatRadioGetRssi(sThreadInstance);
        memcpy(sReceiveFrame[sWriteFrame].mPsdu, frame, frame_length);

        sWriteFrame = (sWriteFrame + 1) % RADIO_FRAMES_BUFFER_SIZE;

        if (sWriteFrame == sReadFrame)
        {
            sDropFrame = true;
        }
    }

exit:
    return;
}

int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
{
    (void)aInstance;
    return DA15000_RECEIVE_SENSITIVITY;
}
