/*
 *
 *    Copyright (c) 2021 Project CHIP Authors
 *    Copyright (c) 2019-2020 Google LLC.
 *    Copyright (c) 2019 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 BL602 Easyflash module.
 */
/* this file behaves like a config.h, comes first */
#include <platform/internal/CHIPDeviceLayerInternal.h>

#include <platform/bouffalolab/BL602/BL602Config.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 <blog.h>
#include <easyflash.h>
#include <utils_log.h>

// 3R: easyflash errno mapping to the CHIP errno

namespace chip {
namespace DeviceLayer {
namespace Internal {

const BL602Config::Key BL602Config::kConfigKey_SerialNum             = { "serial-num" };
const BL602Config::Key BL602Config::kConfigKey_MfrDeviceId           = { "device-id" };
const BL602Config::Key BL602Config::kConfigKey_MfrDeviceCert         = { "device-cert" };
const BL602Config::Key BL602Config::kConfigKey_MfrDeviceICACerts     = { "device-ca-certs" };
const BL602Config::Key BL602Config::kConfigKey_MfrDevicePrivateKey   = { "device-key" };
const BL602Config::Key BL602Config::kConfigKey_HardwareVersion       = { "hardware-ver" };
const BL602Config::Key BL602Config::kConfigKey_ManufacturingDate     = { "mfg-date" };
const BL602Config::Key BL602Config::kConfigKey_SetupPinCode          = { "pin-code" };
const BL602Config::Key BL602Config::kConfigKey_SetupDiscriminator    = { "discriminator" };
const BL602Config::Key BL602Config::kConfigKey_Spake2pIterationCount = { "iteration-count" };
const BL602Config::Key BL602Config::kConfigKey_Spake2pSalt           = { "salt" };
const BL602Config::Key BL602Config::kConfigKey_Spake2pVerifier       = { "verifier" };

// Keys stored in the chip-config namespace
const BL602Config::Key BL602Config::kConfigKey_ServiceConfig               = { "service-config" };
const BL602Config::Key BL602Config::kConfigKey_PairedAccountId             = { "account-id" };
const BL602Config::Key BL602Config::kConfigKey_ServiceId                   = { "service-id" };
const BL602Config::Key BL602Config::kConfigKey_LastUsedEpochKeyId          = { "last-ek-id" };
const BL602Config::Key BL602Config::kConfigKey_FailSafeArmed               = { "fail-safe-armed" };
const BL602Config::Key BL602Config::kConfigKey_WiFiStationSecType          = { "sta-sec-type" };
const BL602Config::Key BL602Config::kConfigKey_OperationalDeviceId         = { "op-device-id" };
const BL602Config::Key BL602Config::kConfigKey_OperationalDeviceCert       = { "op-device-cert" };
const BL602Config::Key BL602Config::kConfigKey_OperationalDeviceICACerts   = { "op-device-ca-certs" };
const BL602Config::Key BL602Config::kConfigKey_OperationalDevicePrivateKey = { "op-device-key" };
const BL602Config::Key BL602Config::kConfigKey_RegulatoryLocation          = { "regulatory-location" };
const BL602Config::Key BL602Config::kConfigKey_CountryCode                 = { "country-code" };
const BL602Config::Key BL602Config::kConfigKey_UniqueId                    = { "unique-id" };

CHIP_ERROR BL602Config::Init()
{
    EfErrCode err = easyflash_init();
    if (EF_NO_ERR == err)
        return CHIP_NO_ERROR;

    log_error("easyflash_init() failed. err: %d\r\n", err);
    return CHIP_ERROR_NO_MEMORY;
}

CHIP_ERROR BL602Config::ReadConfigValue(Key key, bool & val)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    bool tmpVal;
    size_t ret, valLen;

    ret = ef_get_env_blob(key.name, &tmpVal, sizeof(tmpVal), &valLen);
    if (ret <= 0)
    {
        err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
    }
    SuccessOrExit(err);

    val = tmpVal;

exit:
    return err;
}

CHIP_ERROR BL602Config::ReadConfigValue(Key key, uint32_t & val)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    uint32_t tmpVal;
    size_t ret, valLen;

    ret = ef_get_env_blob(key.name, &tmpVal, sizeof(tmpVal), &valLen);
    if (ret <= 0)
    {
        err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
    }
    SuccessOrExit(err);

    val = tmpVal;

exit:
    return err;
}

CHIP_ERROR BL602Config::ReadConfigValue(Key key, uint64_t & val)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    uint64_t tmpVal;
    size_t ret, valLen;

    ret = ef_get_env_blob(key.name, &tmpVal, sizeof(tmpVal), &valLen);
    if (ret <= 0)
    {
        err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
    }
    SuccessOrExit(err);

    val = tmpVal;
exit:
    return err;
}

CHIP_ERROR BL602Config::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen)
{
    CHIP_ERROR err       = CHIP_NO_ERROR;
    char tmpVal[bufSize] = { 0 };
    size_t ret;

    ret = ef_get_env_blob(key.name, tmpVal, sizeof(tmpVal) - 1, NULL);
    if ('\0' == tmpVal[0])
    {
        err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
    }
    SuccessOrExit(err);

    outLen = ret;
    strncpy(buf, tmpVal, outLen);

exit:
    return err;
}

CHIP_ERROR BL602Config::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen)
{
    CHIP_ERROR err       = CHIP_NO_ERROR;
    char tmpVal[bufSize] = { 0 };
    size_t ret;
    size_t savedLen = 0;

    ret = ef_get_env_blob(key.name, tmpVal, sizeof(tmpVal), &savedLen);
    if (0 == savedLen)
    {
        err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
    }
    SuccessOrExit(err);

    outLen = ret;
    memcpy(buf, tmpVal, outLen);

exit:
    return err;
}

CHIP_ERROR BL602Config::WriteConfigValue(Key key, bool val)
{
    CHIP_ERROR err = CHIP_NO_ERROR;

    EfErrCode ret = ef_set_env_blob(key.name, &val, sizeof(val));
    if (ret != EF_NO_ERR)
    {
        err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
    }
    SuccessOrExit(err);

    // ChipLogProgress(DeviceLayer, "Easyflash set: %s = %s", key.name, val ? "true" : "false");
exit:
    return err;
}

CHIP_ERROR BL602Config::WriteConfigValue(Key key, uint32_t val)
{
    CHIP_ERROR err = CHIP_NO_ERROR;

    EfErrCode ret = ef_set_env_blob(key.name, &val, sizeof(val));
    if (ret != EF_NO_ERR)
    {
        err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
    }
    SuccessOrExit(err);

    // ChipLogProgress(DeviceLayer, "Easyflash set: %s = %" PRIu32 " (0x%" PRIX32 ")", key.name, val, val);

exit:
    return err;
}

CHIP_ERROR BL602Config::WriteConfigValue(Key key, uint64_t val)
{
    CHIP_ERROR err = CHIP_NO_ERROR;

    EfErrCode ret = ef_set_env_blob(key.name, &val, sizeof(val));
    if (ret != EF_NO_ERR)
    {
        log_error("WriteConfigValue() failed. key: %s, ret: %d\r\n", key.name, ret);
        err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
    }
    SuccessOrExit(err);

    // ChipLogProgress(DeviceLayer, "Easyflash set: %s = %" PRIu64 " (0x%" PRIX64 ")", key.name, val, val);

exit:
    return err;
}

CHIP_ERROR BL602Config::WriteConfigValueStr(Key key, const char * str)
{
    CHIP_ERROR err = CHIP_NO_ERROR;

    if (str != NULL)
    {
        EfErrCode ret = ef_set_env(key.name, str);
        if (ret != EF_NO_ERR)
        {
            err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
        }
        SuccessOrExit(err);

        // ChipLogProgress(DeviceLayer, "Easyflash set: %s = \"%s\"", key.name, str);
    }
    else
    {
        err = ClearConfigValue(key);
        SuccessOrExit(err);
    }

exit:
    return err;
}

CHIP_ERROR BL602Config::WriteConfigValueStr(Key key, const char * str, size_t strLen)
{
    CHIP_ERROR err;
    chip::Platform::ScopedMemoryBuffer<char> strCopy;

    if (str != NULL)
    {
        strCopy.Calloc(strLen + 1);
        VerifyOrExit(strCopy, err = CHIP_ERROR_NO_MEMORY);
        strncpy(strCopy.Get(), str, strLen);
    }
    err = BL602Config::WriteConfigValueStr(key, strCopy.Get());

exit:
    return err;
}

CHIP_ERROR BL602Config::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen)
{
    CHIP_ERROR err = CHIP_NO_ERROR;

    if (data != NULL)
    {
        EfErrCode ret = ef_set_env_blob(key.name, data, dataLen);
        if (ret != EF_NO_ERR)
        {
            err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
        }
        SuccessOrExit(err);

        // ChipLogProgress(DeviceLayer, "Easyflash set: /%s = (blob length %" PRId32 ")", key.name, (unsigned long )dataLen);
    }
    else
    {
        err = ClearConfigValue(key);
        SuccessOrExit(err);
    }

exit:
    return err;
}

CHIP_ERROR BL602Config::WriteWifiInfo(const char * ssid, const char * passwd)
{
    CHIP_ERROR err = CHIP_NO_ERROR;

#if 0
    if (ssid != NULL && passwd != NULL)
    {
        EfErrCode ret = ef_set_env_blob(kBLConfigKey_wifissid, ssid, strlen(ssid));
        if (ret != EF_NO_ERR)
        {
            err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND;
        }

        ef_set_env_blob(kBLConfigKey_wifipassword, passwd, strlen(passwd));
        if (ret != EF_NO_ERR)
        {
            err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND;
        }
        SuccessOrExit(err);

    }
    else
    {
        //err = ClearConfigValue(ssid);
        //err = ClearConfigValue(passwd);
        SuccessOrExit(err);
    }

exit:
#endif

    return err;
}

CHIP_ERROR BL602Config::ClearConfigValue(Key key)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    EfErrCode ret  = ef_del_env(key.name);
    if (ret != EF_NO_ERR)
    {
        err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND;
    }

    SuccessOrExit(err);

    ChipLogProgress(DeviceLayer, "Easyflash erase: %s", key.name);

exit:
    return err;
}

bool BL602Config::ConfigValueExists(Key key)
{
    CHIP_ERROR err = CHIP_NO_ERROR;
    env_node_obj node;
    bool result = ef_get_env_obj(key.name, &node);
    if (!result)
    {
        err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
    }

    return err == CHIP_NO_ERROR;
}

void BL602Config::RunConfigUnitTest() {}

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