/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *    Copyright (c) 2020 Nest Labs, Inc.
 *    All rights reserved.
 *
 *    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.
 */

/**
 *    @file
 *          Provides an implementation of the PlatformManager object
 *          for K32W platforms using the NXP K32W SDK.
 */
/* this file behaves like a config.h, comes first */
#include <platform/internal/CHIPDeviceLayerInternal.h>

#include <crypto/CHIPCryptoPAL.h>
#include <openthread-system.h>
#include <platform/PlatformManager.h>
#include <platform/internal/GenericPlatformManagerImpl_FreeRTOS.ipp>
#include <platform/nxp/k32w/k32w0/DiagnosticDataProviderImpl.h>

#if CHIP_SYSTEM_CONFIG_USE_LWIP
#include <lwip/tcpip.h>
#endif

#if defined(MBEDTLS_USE_TINYCRYPT)
#include "ecc.h"
#endif

#include <openthread/platform/entropy.h>

#include "MemManager.h"
#include "RNG_Interface.h"
#include "TimersManager.h"
#include "fsl_sha.h"
#include "k32w0-chip-mbedtls-config.h"

namespace chip {
namespace DeviceLayer {

PlatformManagerImpl PlatformManagerImpl::sInstance;

#if defined(MBEDTLS_USE_TINYCRYPT)
osaMutexId_t PlatformManagerImpl::rngMutexHandle = NULL;
#endif

CHIP_ERROR PlatformManagerImpl::InitBoardFwk(void)
{
    CHIP_ERROR err    = CHIP_NO_ERROR;
    char initString[] = "app";
    char * argv[1]    = { 0 };
    argv[0]           = &initString[0];

    SHA_ClkInit(SHA_INSTANCE);

    if (MEM_Init() != MEM_SUCCESS_c)
    {
        err = CHIP_ERROR_NO_MEMORY;
        goto exit;
    }

    if (RNG_Init() != gRngSuccess_d)
    {
        err = CHIP_ERROR_RANDOM_DATA_UNAVAILABLE;
        goto exit;
    }
    RNG_SetPseudoRandomNoSeed(NULL);

    TMR_Init();

    /* Used for OT initializations */
    otSysInit(1, argv);

exit:
    return err;
}

static int app_entropy_source(void * data, unsigned char * output, size_t len, size_t * olen)
{
    otError otErr = otPlatEntropyGet(output, (uint16_t) len);

    if (otErr != OT_ERROR_NONE)
    {
        return -1;
    }

    *olen = len;
    return 0;
}

#if defined(MBEDTLS_USE_TINYCRYPT)
int PlatformManagerImpl::uECC_RNG_Function(uint8_t * dest, unsigned int size)
{
    int res;
    OSA_MutexLock(rngMutexHandle, osaWaitForever_c);
    res = (chip::Crypto::DRBG_get_bytes(dest, size) == CHIP_NO_ERROR) ? size : 0;
    OSA_MutexUnlock(rngMutexHandle);

    return res;
}
#endif

CHIP_ERROR PlatformManagerImpl::_InitChipStack(void)
{
    uint32_t chipType;
    CHIP_ERROR err = CHIP_NO_ERROR;

    // Initialize the configuration system.
    err = Internal::K32WConfig::Init();
    SuccessOrExit(err);

    chipType = Chip_GetType();
    if ((chipType != CHIP_K32W061) && (chipType != CHIP_K32W041) && (chipType != CHIP_K32W041A) && (chipType != CHIP_K32W041AM))
    {
        err = CHIP_ERROR_INTERNAL;
        ChipLogError(DeviceLayer, "Invalid chip type, expected K32W061");

        goto exit;
    }

    mStartTime = System::SystemClock().GetMonotonicTimestamp();

#if CHIP_SYSTEM_CONFIG_USE_LWIP
    // Initialize LwIP.
    tcpip_init(NULL, NULL);
#endif

    err = chip::Crypto::add_entropy_source(app_entropy_source, NULL, 16);
    SuccessOrExit(err);

#if defined(MBEDTLS_USE_TINYCRYPT)
    /* Set RNG function for tinycrypt operations. */
    rngMutexHandle = OSA_MutexCreate();
    VerifyOrExit((NULL != rngMutexHandle), err = CHIP_ERROR_NO_MEMORY);
    uECC_set_rng(PlatformManagerImpl::uECC_RNG_Function);
#endif

    // Call _InitChipStack() on the generic implementation base class
    // to finish the initialization process.
    err = Internal::GenericPlatformManagerImpl_FreeRTOS<PlatformManagerImpl>::_InitChipStack();
    SuccessOrExit(err);

exit:
    return err;
}

void PlatformManagerImpl::_Shutdown()
{
    uint64_t upTime = 0;

    if (GetDiagnosticDataProvider().GetUpTime(upTime) == CHIP_NO_ERROR)
    {
        uint32_t totalOperationalHours = 0;

        if (ConfigurationMgr().GetTotalOperationalHours(totalOperationalHours) == CHIP_NO_ERROR)
        {
            ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours + static_cast<uint32_t>(upTime / 3600));
        }
        else
        {
            ChipLogError(DeviceLayer, "Failed to get total operational hours of the Node");
        }
    }
    else
    {
        ChipLogError(DeviceLayer, "Failed to get current uptime since the Node’s last reboot");
    }

    Internal::GenericPlatformManagerImpl_FreeRTOS<PlatformManagerImpl>::_Shutdown();
}

} // namespace DeviceLayer
} // namespace chip
