/*
 *  Copyright (c) 2018, The OpenThread Authors.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of the copyright holder nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @file
 *   This file includes definitions for non-volatile storage of settings.
 */

#include "settings.hpp"

#include "common/array.hpp"
#include "common/code_utils.hpp"
#include "common/instance.hpp"
#include "common/locator_getters.hpp"
#include "meshcop/dataset.hpp"
#include "thread/mle.hpp"

namespace ot {

RegisterLogModule("Settings");

//---------------------------------------------------------------------------------------------------------------------
// SettingsBase

// LCOV_EXCL_START

#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)

void SettingsBase::NetworkInfo::Log(Action aAction) const
{
    LogInfo("%s NetworkInfo {rloc:0x%04x, extaddr:%s, role:%s, mode:0x%02x, version:%hu, keyseq:0x%x, ...",
            ActionToString(aAction), GetRloc16(), GetExtAddress().ToString().AsCString(),
            Mle::Mle::RoleToString(static_cast<Mle::DeviceRole>(GetRole())), GetDeviceMode(), GetVersion(),
            GetKeySequence());

    LogInfo("... pid:0x%x, mlecntr:0x%x, maccntr:0x%x, mliid:%s}", GetPreviousPartitionId(), GetMleFrameCounter(),
            GetMacFrameCounter(), GetMeshLocalIid().ToString().AsCString());
}

void SettingsBase::ParentInfo::Log(Action aAction) const
{
    LogInfo("%s ParentInfo {extaddr:%s, version:%hu}", ActionToString(aAction), GetExtAddress().ToString().AsCString(),
            GetVersion());
}

#if OPENTHREAD_FTD
void SettingsBase::ChildInfo::Log(Action aAction) const
{
    LogInfo("%s ChildInfo {rloc:0x%04x, extaddr:%s, timeout:%u, mode:0x%02x, version:%hu}", ActionToString(aAction),
            GetRloc16(), GetExtAddress().ToString().AsCString(), GetTimeout(), GetMode(), GetVersion());
}
#endif

#if OPENTHREAD_CONFIG_DUA_ENABLE
void SettingsBase::DadInfo::Log(Action aAction) const
{
    LogInfo("%s DadInfo {DadCounter:%2d}", ActionToString(aAction), GetDadCounter());
}
#endif

#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
void SettingsBase::LogPrefix(Action aAction, Key aKey, const Ip6::Prefix &aPrefix)
{
    LogInfo("%s %s %s", ActionToString(aAction), KeyToString(aKey), aPrefix.ToString().AsCString());
}
#endif

#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE && OPENTHREAD_CONFIG_SRP_CLIENT_SAVE_SELECTED_SERVER_ENABLE
void SettingsBase::SrpClientInfo::Log(Action aAction) const
{
    LogInfo("%s SrpClientInfo {Server:[%s]:%u}", ActionToString(aAction), GetServerAddress().ToString().AsCString(),
            GetServerPort());
}
#endif

#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE && OPENTHREAD_CONFIG_SRP_SERVER_PORT_SWITCH_ENABLE
void SettingsBase::SrpServerInfo::Log(Action aAction) const
{
    LogInfo("%s SrpServerInfo {port:%u}", ActionToString(aAction), GetPort());
}
#endif

#endif // OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)

#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
const char *SettingsBase::ActionToString(Action aAction)
{
    static const char *const kActionStrings[] = {
        "Read",     // (0) kActionRead
        "Saved",    // (1) kActionSave
        "Re-saved", // (2) kActionResave
        "Deleted",  // (3) kActionDelete
#if OPENTHREAD_FTD
        "Added",      // (4) kActionAdd,
        "Removed",    // (5) kActionRemove,
        "Deleted all" // (6) kActionDeleteAll
#endif
    };

    static_assert(0 == kActionRead, "kActionRead value is incorrect");
    static_assert(1 == kActionSave, "kActionSave value is incorrect");
    static_assert(2 == kActionResave, "kActionResave value is incorrect");
    static_assert(3 == kActionDelete, "kActionDelete value is incorrect");
#if OPENTHREAD_FTD
    static_assert(4 == kActionAdd, "kActionAdd value is incorrect");
    static_assert(5 == kActionRemove, "kActionRemove value is incorrect");
    static_assert(6 == kActionDeleteAll, "kActionDeleteAll value is incorrect");
#endif

    return kActionStrings[aAction];
}
#endif // OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)

#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_WARN)
const char *SettingsBase::KeyToString(Key aKey)
{
    static const char *const kKeyStrings[] = {
        "",                  // (0)  (Unused)
        "ActiveDataset",     // (1)  kKeyActiveDataset
        "PendingDataset",    // (2)  kKeyPendingDataset
        "NetworkInfo",       // (3)  kKeyNetworkInfo
        "ParentInfo",        // (4)  kKeyParentInfo
        "ChildInfo",         // (5)  kKeyChildInfo
        "",                  // (6)  kKeyReserved
        "SlaacIidSecretKey", // (7)  kKeySlaacIidSecretKey
        "DadInfo",           // (8)  kKeyDadInfo
        "LegacyOmrPrefix",   // (9)  kKeyLegacyOmrPrefix
        "OnLinkPrefix",      // (10) kKeyOnLinkPrefix
        "SrpEcdsaKey",       // (11) kKeySrpEcdsaKey
        "SrpClientInfo",     // (12) kKeySrpClientInfo
        "SrpServerInfo",     // (13) kKeySrpServerInfo
        "LegacyNat64Prefix", // (14) kKeyLegacyNat64Prefix
        "BrUlaPrefix",       // (15) kKeyBrUlaPrefix
    };

    static_assert(1 == kKeyActiveDataset, "kKeyActiveDataset value is incorrect");
    static_assert(2 == kKeyPendingDataset, "kKeyPendingDataset value is incorrect");
    static_assert(3 == kKeyNetworkInfo, "kKeyNetworkInfo value is incorrect");
    static_assert(4 == kKeyParentInfo, "kKeyParentInfo value is incorrect");
    static_assert(5 == kKeyChildInfo, "kKeyChildInfo value is incorrect");
    static_assert(6 == kKeyReserved, "kKeyReserved value is incorrect");
    static_assert(7 == kKeySlaacIidSecretKey, "kKeySlaacIidSecretKey value is incorrect");
    static_assert(8 == kKeyDadInfo, "kKeyDadInfo value is incorrect");
    static_assert(9 == kKeyLegacyOmrPrefix, "kKeyLegacyOmrPrefix value is incorrect");
    static_assert(10 == kKeyOnLinkPrefix, "kKeyOnLinkPrefix value is incorrect");
    static_assert(11 == kKeySrpEcdsaKey, "kKeySrpEcdsaKey value is incorrect");
    static_assert(12 == kKeySrpClientInfo, "kKeySrpClientInfo value is incorrect");
    static_assert(13 == kKeySrpServerInfo, "kKeySrpServerInfo value is incorrect");
    static_assert(14 == kKeyLegacyNat64Prefix, "kKeyLegacyNat64Prefix value is incorrect");
    static_assert(15 == kKeyBrUlaPrefix, "kKeyBrUlaPrefix value is incorrect");

    static_assert(kLastKey == kKeyBrUlaPrefix, "kLastKey is not valid");

    OT_ASSERT(aKey <= kLastKey);

    return kKeyStrings[aKey];
}
#endif // OT_SHOULD_LOG_AT(OT_LOG_LEVEL_WARN)

// LCOV_EXCL_STOP

//---------------------------------------------------------------------------------------------------------------------
// Settings

// This array contains sensitive keys that should be stored in the secure area.
const uint16_t Settings::kSensitiveKeys[] = {
    SettingsBase::kKeyActiveDataset,
    SettingsBase::kKeyPendingDataset,
    SettingsBase::kKeySrpEcdsaKey,
};

void Settings::Init(void)
{
    Get<SettingsDriver>().Init(kSensitiveKeys, GetArrayLength(kSensitiveKeys));
}

void Settings::Deinit(void)
{
    Get<SettingsDriver>().Deinit();
}

void Settings::Wipe(void)
{
    Get<SettingsDriver>().Wipe();
    LogInfo("Wiped all info");
}

Settings::Key Settings::KeyForDatasetType(MeshCoP::Dataset::Type aType)
{
    return (aType == MeshCoP::Dataset::kActive) ? kKeyActiveDataset : kKeyPendingDataset;
}

Error Settings::SaveOperationalDataset(MeshCoP::Dataset::Type aType, const MeshCoP::Dataset &aDataset)
{
    Key   key   = KeyForDatasetType(aType);
    Error error = Get<SettingsDriver>().Set(key, aDataset.GetBytes(), aDataset.GetSize());

    Log(kActionSave, error, key);

    return error;
}

Error Settings::ReadOperationalDataset(MeshCoP::Dataset::Type aType, MeshCoP::Dataset &aDataset) const
{
    Error    error  = kErrorNone;
    uint16_t length = MeshCoP::Dataset::kMaxSize;

    SuccessOrExit(error = Get<SettingsDriver>().Get(KeyForDatasetType(aType), aDataset.GetBytes(), &length));
    VerifyOrExit(length <= MeshCoP::Dataset::kMaxSize, error = kErrorNotFound);

    aDataset.SetSize(length);

exit:
    return error;
}

Error Settings::DeleteOperationalDataset(MeshCoP::Dataset::Type aType)
{
    Key   key   = KeyForDatasetType(aType);
    Error error = Get<SettingsDriver>().Delete(key);

    Log(kActionDelete, error, key);

    return error;
}

#if OPENTHREAD_FTD
Error Settings::AddChildInfo(const ChildInfo &aChildInfo)
{
    Error error = Get<SettingsDriver>().Add(kKeyChildInfo, &aChildInfo, sizeof(aChildInfo));

    Log(kActionAdd, error, kKeyChildInfo, &aChildInfo);

    return error;
}

Error Settings::DeleteAllChildInfo(void)
{
    Error error = Get<SettingsDriver>().Delete(kKeyChildInfo);

    Log(kActionDeleteAll, error, kKeyChildInfo);

    return error;
}

Settings::ChildInfoIterator::ChildInfoIterator(Instance &aInstance)
    : SettingsBase(aInstance)
    , mIndex(0)
    , mIsDone(false)
{
    Read();
}

void Settings::ChildInfoIterator::Advance(void)
{
    if (!mIsDone)
    {
        mIndex++;
        Read();
    }
}

Error Settings::ChildInfoIterator::Delete(void)
{
    Error error = kErrorNone;

    VerifyOrExit(!mIsDone, error = kErrorInvalidState);
    SuccessOrExit(error = Get<SettingsDriver>().Delete(kKeyChildInfo, mIndex));

exit:
    Log(kActionRemove, error, kKeyChildInfo, &mChildInfo);
    return error;
}

void Settings::ChildInfoIterator::Read(void)
{
    uint16_t length = sizeof(ChildInfo);
    Error    error;

    mChildInfo.Init();
    SuccessOrExit(
        error = Get<SettingsDriver>().Get(kKeyChildInfo, mIndex, reinterpret_cast<uint8_t *>(&mChildInfo), &length));

exit:
    Log(kActionRead, error, kKeyChildInfo, &mChildInfo);
    mIsDone = (error != kErrorNone);
}
#endif // OPENTHREAD_FTD

Error Settings::ReadEntry(Key aKey, void *aValue, uint16_t aMaxLength) const
{
    Error    error;
    uint16_t length = aMaxLength;

    error = Get<SettingsDriver>().Get(aKey, aValue, &length);
    Log(kActionRead, error, aKey, aValue);

    return error;
}

Error Settings::SaveEntry(Key aKey, const void *aValue, void *aPrev, uint16_t aLength)
{
    Error    error      = kErrorNone;
    uint16_t readLength = aLength;
    Action   action     = kActionSave;

    if ((Get<SettingsDriver>().Get(aKey, aPrev, &readLength) == kErrorNone) && (readLength == aLength) &&
        (memcmp(aValue, aPrev, aLength) == 0))
    {
        action = kActionResave;
    }
    else
    {
        error = Get<SettingsDriver>().Set(aKey, aValue, aLength);
    }

    Log(action, error, aKey, aValue);

    return error;
}

Error Settings::DeleteEntry(Key aKey)
{
    Error error = Get<SettingsDriver>().Delete(aKey);

    Log(kActionDelete, error, aKey);

    return error;
}

void Settings::Log(Action aAction, Error aError, Key aKey, const void *aValue)
{
    OT_UNUSED_VARIABLE(aAction);
    OT_UNUSED_VARIABLE(aKey);
    OT_UNUSED_VARIABLE(aError);
    OT_UNUSED_VARIABLE(aValue);

    if (aError != kErrorNone)
    {
        // Log error if log level is at "warn" or higher.

#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_WARN)
        const char *actionText = "";

        switch (aAction)
        {
        case kActionSave:
        case kActionResave:
            actionText = "saving";
            break;

        case kActionDelete:
            VerifyOrExit(aError != kErrorNotFound);
            actionText = "deleting";
            break;

#if OPENTHREAD_FTD
        case kActionAdd:
            actionText = "adding";
            break;

        case kActionRemove:
            VerifyOrExit(aError != kErrorNotFound);
            actionText = "removing";
            break;

        case kActionDeleteAll:
            VerifyOrExit(aError != kErrorNotFound);
            actionText = "deleting all";
            break;
#endif
        case kActionRead:
            ExitNow();
        }

        LogWarn("Error %s %s %s", ErrorToString(aError), actionText, KeyToString(aKey));

#endif // #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_WARN)

        ExitNow();
    }

    // We reach here when `aError` is `kErrorNone`.
    // Log success if log level is at "info" or higher.

#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
    if (aValue != nullptr)
    {
        switch (aKey)
        {
        case kKeyNetworkInfo:
            reinterpret_cast<const NetworkInfo *>(aValue)->Log(aAction);
            break;

        case kKeyParentInfo:
            reinterpret_cast<const ParentInfo *>(aValue)->Log(aAction);
            break;

#if OPENTHREAD_FTD
        case kKeyChildInfo:
            reinterpret_cast<const ChildInfo *>(aValue)->Log(aAction);
            break;
#endif

#if OPENTHREAD_CONFIG_DUA_ENABLE
        case kKeyDadInfo:
            reinterpret_cast<const DadInfo *>(aValue)->Log(aAction);
            break;
#endif

#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
        case kKeyBrUlaPrefix:
        case kKeyLegacyOmrPrefix:
        case kKeyOnLinkPrefix:
        case kKeyLegacyNat64Prefix:
            LogPrefix(aAction, aKey, *reinterpret_cast<const Ip6::Prefix *>(aValue));
            break;
#endif

#if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE && OPENTHREAD_CONFIG_SRP_CLIENT_SAVE_SELECTED_SERVER_ENABLE
        case kKeySrpClientInfo:
            reinterpret_cast<const SrpClientInfo *>(aValue)->Log(aAction);
            break;
#endif

#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE && OPENTHREAD_CONFIG_SRP_SERVER_PORT_SWITCH_ENABLE
        case kKeySrpServerInfo:
            reinterpret_cast<const SrpServerInfo *>(aValue)->Log(aAction);
            break;
#endif

        default:
            // For any other keys, we do not want to include the value
            // in the log, so even if it is given we set `aValue` to
            // `nullptr`. This ensures that we just log the action and
            // the key.
            aValue = nullptr;
            break;
        }
    }

    if (aValue == nullptr)
    {
        LogInfo("%s %s", ActionToString(aAction), KeyToString(aKey));
    }
#endif // OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)

exit:
    return;
}

} // namespace ot

//---------------------------------------------------------------------------------------------------------------------
// Default/weak implementation of settings platform APIs

OT_TOOL_WEAK void otPlatSettingsSetCriticalKeys(otInstance *aInstance, const uint16_t *aKeys, uint16_t aKeysLength)
{
    OT_UNUSED_VARIABLE(aInstance);
    OT_UNUSED_VARIABLE(aKeys);
    OT_UNUSED_VARIABLE(aKeysLength);
}
