/*
 *  Copyright (c) 2020, 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.
 */

#include "flash.hpp"

#if OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE

#include <stdio.h>

#include <openthread/platform/flash.h>

#include "common/code_utils.hpp"
#include "common/instance.hpp"

namespace ot {

const uint32_t ot::Flash::sSwapActive;
const uint32_t ot::Flash::sSwapInactive;

void Flash::Init(void)
{
    RecordHeader record;

    otPlatFlashInit(&GetInstance());

    mSwapSize = otPlatFlashGetSwapSize(&GetInstance());

    for (mSwapIndex = 0;; mSwapIndex++)
    {
        uint32_t swapMarker;

        if (mSwapIndex >= 2)
        {
            Wipe();
            ExitNow();
        }

        otPlatFlashRead(&GetInstance(), mSwapIndex, 0, &swapMarker, sizeof(swapMarker));

        if (swapMarker == sSwapActive)
        {
            break;
        }
    }

    for (mSwapUsed = kSwapMarkerSize; mSwapUsed <= mSwapSize - sizeof(record); mSwapUsed += record.GetSize())
    {
        otPlatFlashRead(&GetInstance(), mSwapIndex, mSwapUsed, &record, sizeof(record));
        if (!record.IsAddBeginSet())
        {
            break;
        }

        if (!record.IsAddCompleteSet())
        {
            break;
        }
    }

    SanitizeFreeSpace();

exit:
    return;
}

void Flash::SanitizeFreeSpace(void)
{
    uint32_t temp;
    bool     sanitizeNeeded = false;

    if (mSwapUsed & 3)
    {
        ExitNow(sanitizeNeeded = true);
    }

    for (uint32_t offset = mSwapUsed; offset < mSwapSize; offset += sizeof(temp))
    {
        otPlatFlashRead(&GetInstance(), mSwapIndex, offset, &temp, sizeof(temp));
        if (temp != ~0U)
        {
            ExitNow(sanitizeNeeded = true);
        }
    }

exit:
    if (sanitizeNeeded)
    {
        Swap();
    }
}

Error Flash::Get(uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength) const
{
    Error        error       = kErrorNotFound;
    uint16_t     valueLength = 0;
    int          index       = 0; // This must be initialized to 0. See [Note] in Delete().
    uint32_t     offset;
    RecordHeader record;

    for (offset = kSwapMarkerSize; offset < mSwapUsed; offset += record.GetSize())
    {
        otPlatFlashRead(&GetInstance(), mSwapIndex, offset, &record, sizeof(record));

        if ((record.GetKey() != aKey) || !record.IsValid())
        {
            continue;
        }

        if (record.IsFirst())
        {
            index = 0;
        }

        if (index == aIndex)
        {
            if (aValue && aValueLength)
            {
                uint16_t readLength = *aValueLength;

                if (readLength > record.GetLength())
                {
                    readLength = record.GetLength();
                }

                otPlatFlashRead(&GetInstance(), mSwapIndex, offset + sizeof(record), aValue, readLength);
            }

            valueLength = record.GetLength();
            error       = kErrorNone;
        }

        index++;
    }

    if (aValueLength)
    {
        *aValueLength = valueLength;
    }

    return error;
}

Error Flash::Set(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
{
    return Add(aKey, true, aValue, aValueLength);
}

Error Flash::Add(uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
{
    bool first = (Get(aKey, 0, nullptr, nullptr) == kErrorNotFound);

    return Add(aKey, first, aValue, aValueLength);
}

Error Flash::Add(uint16_t aKey, bool aFirst, const uint8_t *aValue, uint16_t aValueLength)
{
    Error  error = kErrorNone;
    Record record;

    record.Init(aKey, aFirst);
    record.SetData(aValue, aValueLength);

    OT_ASSERT((mSwapSize - record.GetSize()) >= kSwapMarkerSize);

    if ((mSwapSize - record.GetSize()) < mSwapUsed)
    {
        Swap();
        VerifyOrExit((mSwapSize - record.GetSize()) >= mSwapUsed, error = kErrorNoBufs);
    }

    otPlatFlashWrite(&GetInstance(), mSwapIndex, mSwapUsed, &record, record.GetSize());

    record.SetAddCompleteFlag();
    otPlatFlashWrite(&GetInstance(), mSwapIndex, mSwapUsed, &record, sizeof(RecordHeader));

    mSwapUsed += record.GetSize();

exit:
    return error;
}

bool Flash::DoesValidRecordExist(uint32_t aOffset, uint16_t aKey) const
{
    RecordHeader record;
    bool         rval = false;

    for (; aOffset < mSwapUsed; aOffset += record.GetSize())
    {
        otPlatFlashRead(&GetInstance(), mSwapIndex, aOffset, &record, sizeof(record));

        if (record.IsValid() && record.IsFirst() && (record.GetKey() == aKey))
        {
            ExitNow(rval = true);
        }
    }

exit:
    return rval;
}

void Flash::Swap(void)
{
    uint8_t  dstIndex  = !mSwapIndex;
    uint32_t dstOffset = kSwapMarkerSize;
    Record   record;

    otPlatFlashErase(&GetInstance(), dstIndex);

    for (uint32_t srcOffset = kSwapMarkerSize; srcOffset < mSwapUsed; srcOffset += record.GetSize())
    {
        otPlatFlashRead(&GetInstance(), mSwapIndex, srcOffset, &record, sizeof(RecordHeader));

        VerifyOrExit(record.IsAddBeginSet());

        if (!record.IsValid() || DoesValidRecordExist(srcOffset + record.GetSize(), record.GetKey()))
        {
            continue;
        }

        otPlatFlashRead(&GetInstance(), mSwapIndex, srcOffset, &record, record.GetSize());
        otPlatFlashWrite(&GetInstance(), dstIndex, dstOffset, &record, record.GetSize());
        dstOffset += record.GetSize();
    }

exit:
    otPlatFlashWrite(&GetInstance(), dstIndex, 0, &sSwapActive, sizeof(sSwapActive));
    otPlatFlashWrite(&GetInstance(), mSwapIndex, 0, &sSwapInactive, sizeof(sSwapInactive));

    mSwapIndex = dstIndex;
    mSwapUsed  = dstOffset;
}

Error Flash::Delete(uint16_t aKey, int aIndex)
{
    Error        error = kErrorNotFound;
    int          index = 0; // This must be initialized to 0. See [Note] below.
    RecordHeader record;

    for (uint32_t offset = kSwapMarkerSize; offset < mSwapUsed; offset += record.GetSize())
    {
        otPlatFlashRead(&GetInstance(), mSwapIndex, offset, &record, sizeof(record));

        if ((record.GetKey() != aKey) || !record.IsValid())
        {
            continue;
        }

        if (record.IsFirst())
        {
            index = 0;
        }

        if ((aIndex == index) || (aIndex == -1))
        {
            record.SetDeleted();
            otPlatFlashWrite(&GetInstance(), mSwapIndex, offset, &record, sizeof(record));
            error = kErrorNone;
        }

        /* [Note] If the operation gets interrupted here and aIndex is 0, the next record (index == 1) will never get
         * marked as first. However, this is not actually an issue because all the methods that iterate over the
         * settings area initialize the index to 0, without expecting any record to be effectively marked as first. */

        if ((index == 1) && (aIndex == 0))
        {
            record.SetFirst();
            otPlatFlashWrite(&GetInstance(), mSwapIndex, offset, &record, sizeof(record));
        }

        index++;
    }

    return error;
}

void Flash::Wipe(void)
{
    otPlatFlashErase(&GetInstance(), 0);
    otPlatFlashWrite(&GetInstance(), 0, 0, &sSwapActive, sizeof(sSwapActive));

    mSwapIndex = 0;
    mSwapUsed  = sizeof(sSwapActive);
}

} // namespace ot

#endif // OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
