/*
 *
 *    Copyright (c) 2016-2017 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.
 */
#include <Weave/Support/CodeUtils.h>
#include <Weave/Support/logging/WeaveLogging.h>
#include <Weave/Support/PersistedCounter.h>
#include <Weave/Support/platform/PersistedStorage.h>

#include <stdlib.h>
#include <string.h>

namespace nl {
namespace Weave {

PersistedCounter::PersistedCounter(void) :
    MonotonicallyIncreasingCounter(),
    mStartingCounterValue(0),
    mEpoch(0)
{
    memset(&mId, 0, sizeof(mId));
}

PersistedCounter::~PersistedCounter(void)
{
}

WEAVE_ERROR
PersistedCounter::Init(const nl::Weave::Platform::PersistedStorage::Key aId,
                       uint32_t aEpoch)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    // Store the ID.
    mId = aId;

    // Check and store the epoch.
    VerifyOrExit(aEpoch > 0, err = WEAVE_ERROR_INVALID_INTEGER_VALUE);
    mEpoch = aEpoch;

    // Read our previously-stored starting value.
    err = ReadStartValue(mStartingCounterValue);
    SuccessOrExit(err);

#if WEAVE_CONFIG_PERSISTED_COUNTER_DEBUG_LOGGING
    WeaveLogDetail(EventLogging, "PersistedCounter::Init() aEpoch 0x%x mStartingCounterValue 0x%x", aEpoch, mStartingCounterValue);
#endif

    // Write out the counter value with which we'll start next time we
    // boot up.
    err = WriteStartValue(mStartingCounterValue + mEpoch);
    SuccessOrExit(err);

    // This will set the starting value, after which we're ready.
    err = MonotonicallyIncreasingCounter::Init(mStartingCounterValue);
    SuccessOrExit(err);

exit:
    return err;
}

WEAVE_ERROR
PersistedCounter::Advance(void)
{
    return IncrementCount();
}

bool
PersistedCounter::GetNextValue(uint32_t &aValue)
{
    bool startNewEpoch = false;

    // Increment aValue.
    aValue++;

    // If we've exceeded the value with which we started by aEpoch or
    // more, we need to start a new epoch.
    if ((aValue - mStartingCounterValue) >= mEpoch)
    {
        aValue = mStartingCounterValue + mEpoch;
        startNewEpoch = true;
    }

    return startNewEpoch;
}

WEAVE_ERROR
PersistedCounter::IncrementCount(void)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    // Get the incremented value.
    if (GetNextValue(mCounterValue))
    {
        // Started a new epoch, so write out the next one.
        err = WriteStartValue(mCounterValue + mEpoch);
        SuccessOrExit(err);

        mStartingCounterValue = mCounterValue;
    }

exit:
    return err;
}

WEAVE_ERROR
PersistedCounter::WriteStartValue(uint32_t aStartValue)
{
#if WEAVE_CONFIG_PERSISTED_COUNTER_DEBUG_LOGGING
    WeaveLogDetail(EventLogging, "PersistedCounter::WriteStartValue() aStartValue 0x%x", aStartValue);
#endif

    return nl::Weave::Platform::PersistedStorage::Write(mId, aStartValue);
}

WEAVE_ERROR
PersistedCounter::ReadStartValue(uint32_t &aStartValue)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    aStartValue = 0;

    err = nl::Weave::Platform::PersistedStorage::Read(mId, aStartValue);
    if (err == WEAVE_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND)
    {
        // No previously-stored value, no worries, the counter is initialized to zero.
        // Suppress the error.
        err = WEAVE_NO_ERROR;
    }
    else
    {
        SuccessOrExit(err);
    }

#if WEAVE_CONFIG_PERSISTED_COUNTER_DEBUG_LOGGING
    WeaveLogDetail(EventLogging, "PersistedCounter::ReadStartValue() aStartValue 0x%x", aStartValue);
#endif

exit:
    return err;
}

} // Weave
} // nl
