/*
 *
 *    Copyright (c) 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 <platform/internal/CHIPDeviceLayerInternal.h>

#if CHIP_DEVICE_CONFIG_ENABLE_NFC
#include <platform/NFCManager.h>

#include <lib/support/CHIPPlatformMemory.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/SafeInt.h>
#include <lib/support/logging/CHIPLogging.h>

#include "FunctionLib.h"

namespace chip {
namespace DeviceLayer {

NFCManagerImpl NFCManagerImpl::sInstance;

CHIP_ERROR NFCManagerImpl::_Init()
{
    return CHIP_NO_ERROR;
}

CHIP_ERROR NFCManagerImpl::_StartTagEmulation(const char * payload, size_t payloadLength)
{
    ntagDriverHandleInstance = NTAG_InitDevice((NTAG_ID_T) 0, I2C2);
    assert(ntagDriverHandleInstance);

    CLOCK_EnableClock(kCLOCK_I2c0);
    CLOCK_AttachClk(kOSC32M_to_I2C_CLK);
    HAL_I2C_InitDevice(HAL_I2C_INIT_DEFAULT, kCLOCK_Fro32M, I2C2);

    /* populate the NDEF structure */
    sInstance.ndefUriRecord.recordType    = NDEF_RECORD_TYPE;
    sInstance.ndefUriRecord.recordTypeLen = NDEF_RECORD_TYPE_LEN;
    sInstance.ndefUriRecord.payloadLen    = payloadLength + sizeof(sInstance.ndefUriRecord.uriIdCode);
    sInstance.ndefUriRecord.recordName    = NFC_NDEF_RECORD_NAME;
    sInstance.ndefUriRecord.uriIdCode     = NDEF_URI_ID_CODE;

    if (payloadLength > NDEF_URI_ID_MAX_LENGTH)
    {
        return CHIP_ERROR_BUFFER_TOO_SMALL;
    }
    else
    {
        memcpy(sInstance.ndefUriRecord.uriIdData, payload, payloadLength);
    }

    /* write the NDEF structure to the NTAG EEPROM */
    if (AppNtagWrite(payload) != E_APP_NTAG_NO_ERROR)
    {
        return CHIP_ERROR_INTERNAL;
    }
    else
    {
        sInstance.mIsStarted = TRUE;
    }

    return CHIP_NO_ERROR;
}

CHIP_ERROR NFCManagerImpl::_StopTagEmulation()
{
    uint8_t ndefUriRecordSize = AppNdefUriRecordGetSize(sInstance.ndefUriRecord);

    memset(&sInstance.ndefUriRecord, 0, ndefUriRecordSize);

    if (AppNtagEepromUnlockThenWrite(ndefUriRecordSize) != E_APP_NTAG_NO_ERROR)
    {
        return CHIP_ERROR_INTERNAL;
    }

    /* Stop I2C */
    HAL_I2C_CloseDevice(I2C2);
    NTAG_CloseDevice(sInstance.ntagDriverHandleInstance);
    sInstance.ntagDriverHandleInstance = NULL;

    sInstance.mIsStarted = FALSE;
    return CHIP_NO_ERROR;
}

bool NFCManagerImpl::IsNtagConfigured(eAppNtagError * pNtagError, const char * payload)
{
    uint32_t addrToRead                                                = NTAG_I2C_BLOCK_SIZE;
    uint8_t eepromDataBuf[NDEF_URI_ID_MAX_LENGTH + TERMINATOR_TLV_LEN] = { 0 };
    uint16_t ndefUriRecordSize                                         = AppNdefUriRecordGetSize(sInstance.ndefUriRecord);
    uint8_t ndefUriLen = sInstance.ndefUriRecord.payloadLen - sizeof(sInstance.ndefUriRecord.uriIdCode);

    if (NTAG_ReadBytes(sInstance.ntagDriverHandleInstance, addrToRead, eepromDataBuf, 2))
    {
        *pNtagError = E_APP_NTAG_READ_ERROR;
        return FALSE;
    }

    /* see also http://apps4android.org/nfc-specifications/NFCForum-TS-Type-2-Tag_1.1.pdf, chapter 2.3 */
    if (eepromDataBuf[0] != 0x03 || eepromDataBuf[1] != ndefUriRecordSize)
    {
        return FALSE;
    }

    /* read the NdefUriRecord from the EEPROM */
    addrToRead += 2;
    if (NTAG_ReadBytes(sInstance.ntagDriverHandleInstance, addrToRead, eepromDataBuf, ndefUriRecordSize))
    {
        *pNtagError = E_APP_NTAG_READ_ERROR;
        return FALSE;
    }

    /* verify if the ndefUriRecord is the same as the one flashed in the the EEPROM:
     * If it is, then the NTAG is already configured.
     */
    return (payload && !memcmp(sInstance.ndefUriRecord.uriIdData, payload, ndefUriLen) &&
            !memcmp((uint8_t *) &(sInstance.ndefUriRecord), eepromDataBuf, ndefUriRecordSize));
}

NFCManagerImpl::eAppNtagError NFCManagerImpl::AppNtagWrite(const char * payload)
{
    eAppNtagError ntagErr = E_APP_NTAG_NO_ERROR;
    uint8_t byte0         = 0;
    uint8_t i             = 0;
    bool_t i2cAddrFound   = FALSE;
    bool_t isConfigured   = FALSE;

    do
    {
        /* Try to access the device at default I2C address */
        if (NTAG_ReadBytes(sInstance.ntagDriverHandleInstance, 0, &byte0, sizeof(byte0)))
        {
            /* Try now with the 0x02 I2C address */
            NTAG_SetNtagI2cAddress(sInstance.ntagDriverHandleInstance, 0x2);
            if (!NTAG_ReadBytes(sInstance.ntagDriverHandleInstance, 0, &byte0, sizeof(byte0)))
            {
                i2cAddrFound = TRUE;
            }
            else
            {
                /* Loop to try to find a valid i2c address */
                for (i = 0; i < 0xFF; i++)
                {
                    if (i == 2 || i == 0x55) /* Skip default and 0x02 I2C address */
                    {
                        continue;
                    }

                    NTAG_SetNtagI2cAddress(sInstance.ntagDriverHandleInstance, i);
                    if (!NTAG_ReadBytes(sInstance.ntagDriverHandleInstance, 0, &byte0, sizeof(byte0)))
                    {
                        i2cAddrFound = TRUE;
                        break;
                    }
                }
            }

            if (!i2cAddrFound)
            {
                ntagErr = E_APP_NTAG_READ_ERROR;
                break;
            }
        }

        isConfigured = IsNtagConfigured(&ntagErr, payload);
        if (ntagErr != E_APP_NTAG_NO_ERROR)
        {
            break;
        }

        if (!isConfigured)
        {
            ntagErr = AppNtagEepromUnlockThenWrite(0);
        }

    } while (0);

    return ntagErr;
}

bool NFCManagerImpl::AppNtagEepromWrite(uint8_t originalSize)
{
    bool wasWritten      = FALSE;
    uint32_t ndefSize    = AppNdefUriRecordGetSize(sInstance.ndefUriRecord);
    uint32_t addrToWrite = NTAG_I2C_BLOCK_SIZE;
    uint8_t buf[4];
    uint8_t terminatorTLV = 0xFE;

    do
    {
        if (!sInstance.ndefUriRecord.payloadLen)
        {
            if (NTAG_WriteBytes(sInstance.ntagDriverHandleInstance, addrToWrite, (uint8_t *) &(sInstance.ndefUriRecord),
                                originalSize + sizeof(terminatorTLV)))
            {
                break;
            }
        }
        else
        {
            buf[0] = 0x3;
            buf[1] = ndefSize;
            if (NTAG_WriteBytes(sInstance.ntagDriverHandleInstance, addrToWrite, buf, 2))
            {
                break;
            }

            addrToWrite += 2;

            if (NTAG_WriteBytes(sInstance.ntagDriverHandleInstance, addrToWrite, (uint8_t *) &(sInstance.ndefUriRecord), ndefSize))
            {
                break;
            }

            addrToWrite += ndefSize;

            if (NTAG_WriteBytes(sInstance.ntagDriverHandleInstance, addrToWrite, &terminatorTLV, 1))
            {
                break;
            }
        }

        wasWritten = TRUE;
    } while (0);

    return wasWritten;
}

NFCManagerImpl::eAppNtagError NFCManagerImpl::AppNtagEepromUnlockThenWrite(uint8_t originalSize)
{
    eAppNtagError ntagErr = E_APP_NTAG_NO_ERROR;

    do
    {
        /* Unlock write access */
        ntagErr = AppNtagUnlockWriteAccess();
        if (ntagErr != E_APP_NTAG_NO_ERROR)
        {
            break;
        }

        /* Write the NDEF URI */
        if (!AppNtagEepromWrite(originalSize))
        {
            ntagErr = E_APP_NTAG_WRITE_ERROR;
        }

        /* Lock write access */
        AppNtagLockWriteAccess();
    } while (0);

    return ntagErr;
}

uint8_t NFCManagerImpl::AppNdefUriRecordGetSize(NdefUriRecord_t ndefUriRecord)
{
    return sizeof(sInstance.ndefUriRecord.recordType) + sizeof(sInstance.ndefUriRecord.recordTypeLen) +
        sizeof(sInstance.ndefUriRecord.payloadLen) + sInstance.ndefUriRecord.payloadLen +
        sizeof(sInstance.ndefUriRecord.recordName);
}

NFCManagerImpl::eAppNtagError NFCManagerImpl::AppNtagLockWriteAccess(void)
{
    eAppNtagError ntagErr = E_APP_NTAG_NO_ERROR;

    uint8_t bytes[NTAG_I2C_BLOCK_SIZE];
    FLib_MemSet(bytes, 0x0, sizeof(bytes));

    do
    {
        /* Try to read the block 0 */
        if (NTAG_ReadBytes(sInstance.ntagDriverHandleInstance, 0, bytes, sizeof(bytes)))
        {
            ntagErr = E_APP_NTAG_READ_ERROR;
            break;
        }

        /* Set the Capability Container (CC) */
        bytes[3] = 0xE1; /* Indicates that NDEF data is present inside the tag */
        bytes[4] = 0x10; /* Indicates to support the version 1.0 */
        bytes[5] = 0xE9; /* Indicates 1864 bytes of memory size assigned to the data area */
        bytes[6] = 0x0F; /* Indicates read only access granted */

        if (NTAG_WriteBytes(sInstance.ntagDriverHandleInstance, 0, bytes, sizeof(bytes)))
        {
            ntagErr = E_APP_NTAG_WRITE_ERROR;
        }
    } while (0);

    return ntagErr;
}

NFCManagerImpl::eAppNtagError NFCManagerImpl::AppNtagUnlockWriteAccess(void)
{
    eAppNtagError ntagErr = E_APP_NTAG_NO_ERROR;

    uint8_t bytes[NTAG_I2C_BLOCK_SIZE];
    FLib_MemSet(bytes, 0x0, sizeof(bytes));

    do
    {
        /* Try to read the block 0 */
        if (NTAG_ReadBytes(sInstance.ntagDriverHandleInstance, 0, bytes, sizeof(bytes)))
        {
            ntagErr = E_APP_NTAG_READ_ERROR;
            break;
        }

        /* Set the Capability Container (CC) */
        bytes[12] = 0xE1; /* Indicates that NDEF data is present inside the tag */
        bytes[13] = 0x10; /* Indicates to support the version 1.0 */
        bytes[14] = 0xE9; /* Indicates 1864 bytes of memory size assigned to the data area */
        bytes[15] = 0x00; /* Indicates read and write access granted without any security */

        if (NTAG_WriteBytes(sInstance.ntagDriverHandleInstance, 0, bytes, sizeof(bytes)))
        {
            ntagErr = E_APP_NTAG_WRITE_ERROR;
        }

    } while (0);

    return ntagErr;
}

} // namespace DeviceLayer
} // namespace chip
#endif
