/*
 *
 *    Copyright (c) 2020-2022 Project CHIP Authors
 *    Copyright (c) 2019-2020 Google LLC.
 *    Copyright (c) 2018 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
 *          Utilities for interacting with the the ESP32 "NVS" key-value store.
 */
/* this file behaves like a config.h, comes first */
#include <platform/internal/CHIPDeviceLayerInternal.h>

#include <platform/mbed/MbedConfig.h>

#include <lib/core/CHIPEncoding.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/CHIPMemString.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>

#include "kvstore_global_api/kvstore_global_api.h"
#include "platform/mbed_error.h"

namespace chip {
namespace DeviceLayer {
namespace Internal {

// *** CAUTION ***: Changing the names or namespaces of these values will *break* existing devices.

#define STR_EXPAND(tok) #tok

// Note: An external mbed parameter could be useful so an application can put
// chip NVS values in a single place
#define CHIP_CONFIG_KV_STORE_PARTITION STR_EXPAND(MBED_CONF_STORAGE_DEFAULT_KV)

// NVS namespaces used to store device configuration information.
#define CHIP_CONFIG_FACTORY_PREFIX "chip-factory-"
#define CHIP_CONFIG_CONFIG_PREFIX "chip-config-"
#define CHIP_CONFIG_COUNTER_PREFIX "chip-counters-"

#define FACTORY_KEY(key) CHIP_CONFIG_KV_STORE_PARTITION CHIP_CONFIG_FACTORY_PREFIX key
#define CONFIG_KEY(key) CHIP_CONFIG_KV_STORE_PARTITION CHIP_CONFIG_CONFIG_PREFIX key
#define COUNTER_KEY(key) CHIP_CONFIG_KV_STORE_PARTITION CHIP_CONFIG_COUNTER_PREFIX key

const char MbedConfig::kConfigNamespace_ChipFactory[]  = CHIP_CONFIG_KV_STORE_PARTITION CHIP_CONFIG_FACTORY_PREFIX;
const char MbedConfig::kConfigNamespace_ChipConfig[]   = CHIP_CONFIG_KV_STORE_PARTITION CHIP_CONFIG_CONFIG_PREFIX;
const char MbedConfig::kConfigNamespace_ChipCounters[] = CHIP_CONFIG_KV_STORE_PARTITION CHIP_CONFIG_COUNTER_PREFIX;

// Keys stored in the chip-factory namespace
const MbedConfig::Key MbedConfig::kConfigKey_SerialNum             = { FACTORY_KEY("serial-num") };
const MbedConfig::Key MbedConfig::kConfigKey_MfrDeviceId           = { FACTORY_KEY("device-id") };
const MbedConfig::Key MbedConfig::kConfigKey_MfrDeviceCert         = { FACTORY_KEY("device-cert") };
const MbedConfig::Key MbedConfig::kConfigKey_MfrDeviceICACerts     = { FACTORY_KEY("device-ca-certs") };
const MbedConfig::Key MbedConfig::kConfigKey_MfrDevicePrivateKey   = { FACTORY_KEY("device-key") };
const MbedConfig::Key MbedConfig::kConfigKey_HardwareVersion       = { FACTORY_KEY("hardware-ver") };
const MbedConfig::Key MbedConfig::kConfigKey_ManufacturingDate     = { FACTORY_KEY("mfg-date") };
const MbedConfig::Key MbedConfig::kConfigKey_SetupPinCode          = { FACTORY_KEY("pin-code") };
const MbedConfig::Key MbedConfig::kConfigKey_SetupDiscriminator    = { FACTORY_KEY("discriminator") };
const MbedConfig::Key MbedConfig::kConfigKey_Spake2pIterationCount = { FACTORY_KEY("iteration-count") };
const MbedConfig::Key MbedConfig::kConfigKey_Spake2pSalt           = { FACTORY_KEY("salt") };
const MbedConfig::Key MbedConfig::kConfigKey_Spake2pVerifier       = { FACTORY_KEY("verifier") };

// Keys stored in the chip-config namespace
const MbedConfig::Key MbedConfig::kConfigKey_ServiceConfig      = { CONFIG_KEY("service-config") };
const MbedConfig::Key MbedConfig::kConfigKey_PairedAccountId    = { CONFIG_KEY("account-id") };
const MbedConfig::Key MbedConfig::kConfigKey_ServiceId          = { CONFIG_KEY("service-id") };
const MbedConfig::Key MbedConfig::kConfigKey_LastUsedEpochKeyId = { CONFIG_KEY("last-ek-id") };
const MbedConfig::Key MbedConfig::kConfigKey_FailSafeArmed      = { CONFIG_KEY("fail-safe-armed") };
const MbedConfig::Key MbedConfig::kConfigKey_RegulatoryLocation = { CONFIG_KEY("regulatory-location") };
const MbedConfig::Key MbedConfig::kConfigKey_CountryCode        = { CONFIG_KEY("country-code") };
const MbedConfig::Key MbedConfig::kConfigKey_UniqueId           = { CONFIG_KEY("unique-id") };

// Keys stored in the Chip-counters namespace
const MbedConfig::Key MbedConfig::kCounterKey_RebootCount           = { COUNTER_KEY("reboot-count") };
const MbedConfig::Key MbedConfig::kCounterKey_UpTime                = { COUNTER_KEY("up-time") };
const MbedConfig::Key MbedConfig::kCounterKey_TotalOperationalHours = { COUNTER_KEY("total-hours") };

CHIP_ERROR MbedConfig::ReadConfigValue(Key key, bool & val)
{
    if (!ConfigValueExists(key))
    {
        return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
    }

    size_t actual_size = 0;
    int err            = kv_get(key, reinterpret_cast<void *>(&val), sizeof(val), &actual_size);

    if (err != MBED_SUCCESS)
    {
        return CHIP_ERROR_INTERNAL;
    }

    if (actual_size != sizeof(val))
    {
        return CHIP_ERROR_BAD_REQUEST;
    }

    return CHIP_NO_ERROR;
}

CHIP_ERROR MbedConfig::ReadConfigValue(Key key, uint32_t & val)
{
    if (!ConfigValueExists(key))
    {
        return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
    }

    size_t actual_size = 0;
    int err            = kv_get(key, reinterpret_cast<void *>(&val), sizeof(val), &actual_size);

    if (err != MBED_SUCCESS)
    {
        return CHIP_ERROR_INTERNAL;
    }

    if (actual_size != sizeof(val))
    {
        return CHIP_ERROR_BAD_REQUEST;
    }

    return CHIP_NO_ERROR;
}

CHIP_ERROR MbedConfig::ReadConfigValue(Key key, uint64_t & val)
{
    if (!ConfigValueExists(key))
    {
        return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
    }

    size_t actual_size = 0;
    int err            = kv_get(key, &val, sizeof(val), &actual_size);

    if (err != MBED_SUCCESS)
    {
        return CHIP_ERROR_INTERNAL;
    }

    if (actual_size != sizeof(val))
    {
        return CHIP_ERROR_BAD_REQUEST;
    }

    return CHIP_NO_ERROR;
}

CHIP_ERROR MbedConfig::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen)
{
    CHIP_ERROR err = ReadConfigValueBin(key, reinterpret_cast<uint8_t *>(buf), bufSize, outLen);
    // Note: The system expect the trailing null to be added.
    if (err != CHIP_NO_ERROR)
    {
        return err;
    }
    if (outLen >= bufSize)
    {
        return CHIP_ERROR_INVALID_ARGUMENT;
    }
    buf[outLen] = 0;
    return CHIP_NO_ERROR;
}

CHIP_ERROR MbedConfig::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen)
{
    if (!ConfigValueExists(key))
    {
        return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
    }

    kv_info_t info;

    int err = kv_get_info(key, &info);
    if (err != MBED_SUCCESS)
    {
        return CHIP_ERROR_INTERNAL;
    }

    err = kv_get(key, reinterpret_cast<void *>(buf), bufSize, &outLen);
    if (err != MBED_SUCCESS)
    {
        return CHIP_ERROR_INTERNAL;
    }

    if (bufSize < info.size)
    {
        return CHIP_ERROR_BUFFER_TOO_SMALL;
    }

    return CHIP_NO_ERROR;
}

CHIP_ERROR MbedConfig::WriteConfigValue(Key key, bool val)
{
    int err = kv_set(key, reinterpret_cast<const void *>(&val), sizeof(val), 0);
    return err == MBED_SUCCESS ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL;
}

CHIP_ERROR MbedConfig::WriteConfigValue(Key key, uint32_t val)
{
    int err = kv_set(key, reinterpret_cast<const void *>(&val), sizeof(val), 0);
    return err == MBED_SUCCESS ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL;
}

CHIP_ERROR MbedConfig::WriteConfigValue(Key key, uint64_t val)
{
    int err = kv_set(key, reinterpret_cast<void *>(&val), sizeof(val), 0);
    return err == MBED_SUCCESS ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL;
}

CHIP_ERROR MbedConfig::WriteConfigValueStr(Key key, const char * str)
{
    return WriteConfigValueBin(key, reinterpret_cast<const uint8_t *>(str), strlen(str));
}

CHIP_ERROR MbedConfig::WriteConfigValueStr(Key key, const char * str, size_t strLen)
{
    return WriteConfigValueBin(key, reinterpret_cast<const uint8_t *>(str), strLen);
}

CHIP_ERROR MbedConfig::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen)
{
    // Two different behavior: If the pointer is not null, the value is updated
    // or create. If the pointer is null, the key is removed if it exist.
    if (data != nullptr)
    {
        int err = kv_set(key, reinterpret_cast<const void *>(data), dataLen, 0);
        return err == MBED_SUCCESS ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL;
    }
    else if (ConfigValueExists(key))
    {
        return ClearConfigValue(key);
    }
    else
    {
        // Nothing to do, data is null and the key does not exist.
        return CHIP_NO_ERROR;
    }
}

CHIP_ERROR MbedConfig::ClearConfigValue(Key key)
{
    int err = kv_remove(key);
    return err == MBED_SUCCESS ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL;
}

bool MbedConfig::ConfigValueExists(Key key)
{
    kv_info_t info;
    int err = kv_get_info(key, &info);
    return err == MBED_SUCCESS ? true : false;
}

CHIP_ERROR MbedConfig::FactoryResetConfig()
{
    // kv_reset is not used, we want to preserve other setting and factory
    // configuration
    auto err = ClearNamespace(kConfigNamespace_ChipConfig);
    if (err != CHIP_NO_ERROR)
    {
        return err;
    }
    return ClearNamespace(kConfigNamespace_ChipCounters);
}

CHIP_ERROR MbedConfig::ConstructCounterKey(Key id, char * buf, size_t bufSize)
{
    auto length = snprintf(buf, bufSize - 1, CHIP_CONFIG_KV_STORE_PARTITION CHIP_CONFIG_COUNTER_PREFIX "%s", id);
    if (length < 0)
    {
        return CHIP_ERROR_INTERNAL;
    }
    else if ((size_t) length > (bufSize - 1))
    {
        return CHIP_ERROR_INVALID_ARGUMENT;
    }
    else
    {
        return CHIP_NO_ERROR;
    }
}

CHIP_ERROR MbedConfig::ReadCounter(Key counterId, uint32_t & value)
{
    char key[50] = { 0 };
    auto err     = ConstructCounterKey(counterId, key, sizeof(key));
    if (err != CHIP_NO_ERROR)
    {
        return err;
    }

    return ReadConfigValue(key, value);
}

CHIP_ERROR MbedConfig::WriteCounter(Key counterId, uint32_t value)
{
    char key[50] = { 0 };
    auto err     = ConstructCounterKey(counterId, key, sizeof(key));
    if (err != CHIP_NO_ERROR)
    {
        return err;
    }

    return WriteConfigValue(key, value);
}

CHIP_ERROR MbedConfig::ClearNamespace(const char * ns)
{
    kv_iterator_t it;
    char key[50];
    int err = kv_iterator_open(&it, ns);
    if (err)
    {
        return CHIP_ERROR_INTERNAL;
    }
    while (kv_iterator_next(it, key, sizeof(key)) != MBED_ERROR_ITEM_NOT_FOUND)
    {
        kv_remove(key);
        memset(key, 0, sizeof(key));
    }

    err = kv_iterator_close(it);
    return err == MBED_SUCCESS ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL;
}

void MbedConfig::RunConfigUnitTest()
{
    // Run common unit test.
    ::chip::DeviceLayer::Internal::RunConfigUnitTest<MbedConfig>();
}

} // namespace Internal
} // namespace DeviceLayer
} // namespace chip
