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

#include <platform/NFCManager.h>

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

#include <nfc/ndef/uri_msg.h>
#include <nfc/ndef/uri_rec.h>
#include <nfc_t2t_lib.h>
#include <zephyr.h>

namespace chip {
namespace DeviceLayer {
namespace {
void nfcCallback(void * /* context */, nfc_t2t_event_t, const uint8_t * /* data */, size_t /* data_length */) {}
} // namespace

NFCManagerImpl NFCManagerImpl::sInstance;

CHIP_ERROR NFCManagerImpl::_Init()
{
    mIsStarted = false;
    return nfc_t2t_setup(nfcCallback, nullptr) ? CHIP_ERROR_INTERNAL : CHIP_NO_ERROR;
}

CHIP_ERROR NFCManagerImpl::_StartTagEmulation(const char * payload, size_t payloadLength)
{
    CHIP_ERROR error    = CHIP_NO_ERROR;
    int result          = 0;
    uint32_t ndefLength = sizeof(mNdefBuffer);

    VerifyOrExit(!mIsStarted, error = CHIP_ERROR_INCORRECT_STATE);
    VerifyOrExit(CanCastTo<uint8_t>(payloadLength), error = CHIP_ERROR_BUFFER_TOO_SMALL);

    result = nfc_ndef_uri_msg_encode(NFC_URI_NONE, reinterpret_cast<const uint8_t *>(payload), static_cast<uint8_t>(payloadLength),
                                     mNdefBuffer, &ndefLength);

    if (result)
    {
        ChipLogError(DeviceLayer, "nfc_ndef_uri_msg_encode() failed: %d", result);
        ExitNow(error = CHIP_ERROR_BUFFER_TOO_SMALL);
    }

    result = nfc_t2t_payload_set(mNdefBuffer, ndefLength);

    if (result)
    {
        ChipLogError(DeviceLayer, "nfc_t2t_payload_set() failed: %d", result);
        ExitNow(error = CHIP_ERROR_INTERNAL);
    }

    result = nfc_t2t_emulation_start();

    if (result)
    {
        ChipLogError(DeviceLayer, "nfc_t2t_emulation_start() failed: %d", result);
        ExitNow(error = CHIP_ERROR_INTERNAL);
    }

    ChipLogProgress(DeviceLayer, "NFC Tag emulation started");
    mIsStarted = true;

exit:
    if (error != CHIP_NO_ERROR)
        ChipLogError(DeviceLayer, "Starting NFC Tag emulation failed: %" CHIP_ERROR_FORMAT, error.Format());
    return error;
}

CHIP_ERROR NFCManagerImpl::_StopTagEmulation()
{
    VerifyOrReturnError(mIsStarted, CHIP_NO_ERROR);

    int result = nfc_t2t_emulation_stop();

    if (result)
    {
        ChipLogError(DeviceLayer, "Stopping NFC Tag emulation failed: %d", result);
        return CHIP_ERROR_INTERNAL;
    }

    ChipLogProgress(DeviceLayer, "NFC Tag emulation stopped");
    mIsStarted = false;
    return CHIP_NO_ERROR;
}

} // namespace DeviceLayer
} // namespace chip
