/*
 *
 *    Copyright (c) 2021-2022 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 <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" };

const BL602Config::Key BL602Config::kCounterKey_RebootCount           = { "reboot-count" };
const BL602Config::Key BL602Config::kCounterKey_TotalOperationalHours = { "total-hours" };

CHIP_ERROR BL602Config::Init()
{
    return CHIP_NO_ERROR;
}

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

    ef_get_env_blob(key.name, &val, 1, &valLen);
    if (0 == valLen)
    {
        err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
    }

    return err;
}

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

    ef_get_env_blob(key.name, &val, sizeof(val), &valLen);
    if (0 == valLen)
    {
        err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
    }

    return err;
}

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

    ef_get_env_blob(key.name, &val, sizeof(val), &valLen);
    if (0 == valLen)
    {
        err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
    }

    return err;
}

CHIP_ERROR BL602Config::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen)
{
    CHIP_ERROR err = CHIP_NO_ERROR;

    outLen = 0;
    ef_get_env_blob(key.name, buf, bufSize, &outLen);
    if (0 == outLen)
    {
        err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
    }

    return err;
}

CHIP_ERROR BL602Config::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen)
{
    CHIP_ERROR err = CHIP_NO_ERROR;

    ef_get_env_blob(key.name, buf, bufSize, &outLen);
    if (0 == outLen)
    {
        err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND;
    }

    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", StringOrNullMarker(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);
        Platform::CopyString(strCopy.Get(), strLen + 1, str);
    }
    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", StringOrNullMarker(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
