/*
 *    Copyright (c) 2017, 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 implements a spinel decoder.
 */

#include <openthread/config.h>

#include "spinel_decoder.hpp"

#include "common/code_utils.hpp"

namespace ot {
namespace Ncp {

SpinelDecoder::SpinelDecoder(void)
    : mFrame(NULL)
    , mLength(0)
    , mIndex(0)
    , mEnd(0)
    , mNumOpenStructs(0)
    , mSavedNumOpenStructs(0)
    , mSavedIndex(0)
    , mSavedEnd(0)
{
}

void SpinelDecoder::Init(const uint8_t *aFrame, uint16_t aLength)
{
    mFrame  = aFrame;
    mLength = (mFrame != NULL) ? aLength : 0;

    Reset();
    ClearSavedPosition();
}

void SpinelDecoder::Reset(void)
{
    mIndex          = 0;
    mEnd            = mLength;
    mNumOpenStructs = 0;
    ClearSavedPosition();
}

otError SpinelDecoder::ReadBool(bool &aBool)
{
    otError error = OT_ERROR_NONE;
    uint8_t byte;

    SuccessOrExit(error = ReadUint8(byte));

    // Boolean value are encoded in 8-bits as either 0x00 or 0x01. All other values are illegal.
    if (byte == 0x00)
    {
        aBool = false;
    }
    else if (byte == 0x01)
    {
        aBool = true;
    }
    else
    {
        error = OT_ERROR_PARSE;
    }

exit:
    return error;
}

otError SpinelDecoder::ReadUint8(uint8_t &aUint8)
{
    otError error = OT_ERROR_NONE;

    VerifyOrExit(mIndex + sizeof(uint8_t) <= mEnd, error = OT_ERROR_PARSE);
    aUint8 = mFrame[mIndex];
    mIndex += sizeof(uint8_t);

exit:
    return error;
}

otError SpinelDecoder::ReadInt8(int8_t &aInt8)
{
    otError error = OT_ERROR_NONE;
    uint8_t byte;

    SuccessOrExit(error = ReadUint8(byte));
    aInt8 = static_cast<int8_t>(byte);

exit:
    return error;
}

otError SpinelDecoder::ReadUint16(uint16_t &aUint16)
{
    otError error = OT_ERROR_NONE;

    VerifyOrExit(mIndex + sizeof(uint16_t) <= mEnd, error = OT_ERROR_PARSE);

    aUint16 = static_cast<uint16_t>(mFrame[mIndex] | (mFrame[mIndex + 1] << 8));

    mIndex += sizeof(uint16_t);

exit:
    return error;
}

otError SpinelDecoder::ReadInt16(int16_t &aInt16)
{
    otError  error = OT_ERROR_NONE;
    uint16_t u16;

    SuccessOrExit(error = ReadUint16(u16));
    aInt16 = static_cast<int16_t>(u16);

exit:
    return error;
}

otError SpinelDecoder::ReadUint32(uint32_t &aUint32)
{
    otError error = OT_ERROR_NONE;

    VerifyOrExit(mIndex + sizeof(uint32_t) <= mEnd, error = OT_ERROR_PARSE);

    aUint32 = ((static_cast<uint32_t>(mFrame[mIndex + 0]) << 0) | (static_cast<uint32_t>(mFrame[mIndex + 1]) << 8) |
               (static_cast<uint32_t>(mFrame[mIndex + 2]) << 16) | (static_cast<uint32_t>(mFrame[mIndex + 3]) << 24));

    mIndex += sizeof(uint32_t);

exit:
    return error;
}

otError SpinelDecoder::ReadInt32(int32_t &aInt32)
{
    otError  error = OT_ERROR_NONE;
    uint32_t u32;

    SuccessOrExit(error = ReadUint32(u32));
    aInt32 = static_cast<int32_t>(u32);

exit:
    return error;
}

otError SpinelDecoder::ReadUint64(uint64_t &aUint64)
{
    otError error = OT_ERROR_NONE;

    VerifyOrExit(mIndex + sizeof(uint64_t) <= mEnd, error = OT_ERROR_PARSE);

    aUint64 = ((static_cast<uint64_t>(mFrame[mIndex + 0]) << 0) | (static_cast<uint64_t>(mFrame[mIndex + 1]) << 8) |
               (static_cast<uint64_t>(mFrame[mIndex + 2]) << 16) | (static_cast<uint64_t>(mFrame[mIndex + 3]) << 24) |
               (static_cast<uint64_t>(mFrame[mIndex + 4]) << 32) | (static_cast<uint64_t>(mFrame[mIndex + 5]) << 40) |
               (static_cast<uint64_t>(mFrame[mIndex + 6]) << 48) | (static_cast<uint64_t>(mFrame[mIndex + 7]) << 56));

    mIndex += sizeof(uint64_t);

exit:
    return error;
}

otError SpinelDecoder::ReadInt64(int64_t &aInt64)
{
    otError  error = OT_ERROR_NONE;
    uint64_t u64;

    SuccessOrExit(error = ReadUint64(u64));
    aInt64 = static_cast<int64_t>(u64);

exit:
    return error;
}

otError SpinelDecoder::ReadUintPacked(unsigned int &aUint)
{
    otError        error = OT_ERROR_NONE;
    spinel_ssize_t parsedLen;
    unsigned int   uint;

    parsedLen = spinel_packed_uint_decode(&mFrame[mIndex], mEnd - mIndex, &uint);
    VerifyOrExit(parsedLen > 0, error = OT_ERROR_PARSE);

    mIndex += parsedLen;
    aUint = uint;

exit:
    return error;
}

// Reads an item of given size and updates the pointer `aPtr`.
otError SpinelDecoder::ReadItem(const uint8_t **aPtr, uint16_t aSize)
{
    otError error = OT_ERROR_NONE;

    VerifyOrExit(mIndex + aSize <= mEnd, error = OT_ERROR_PARSE);

    *aPtr = &mFrame[mIndex];

    mIndex += aSize;

exit:
    return error;
}

otError SpinelDecoder::ReadIp6Address(spinel_ipv6addr_t &aIp6Addr)
{
    otError                  error = OT_ERROR_NONE;
    const spinel_ipv6addr_t *ipv6AddrPtr;

    SuccessOrExit(error = ReadIp6Address(ipv6AddrPtr));
    aIp6Addr = *ipv6AddrPtr;

exit:
    return error;
}

otError SpinelDecoder::ReadIp6Address(otIp6Address &aIp6Addr)
{
    otError             error = OT_ERROR_NONE;
    const otIp6Address *ipv6AddrPtr;

    SuccessOrExit(error = ReadIp6Address(ipv6AddrPtr));
    aIp6Addr = *ipv6AddrPtr;

exit:
    return error;
}

otError SpinelDecoder::ReadEui64(spinel_eui64_t &aEui64)
{
    otError               error = OT_ERROR_NONE;
    const spinel_eui64_t *eui64Ptr;

    SuccessOrExit(error = ReadEui64(eui64Ptr));
    aEui64 = *eui64Ptr;

exit:
    return error;
}

otError SpinelDecoder::ReadEui64(otExtAddress &aEui64)
{
    otError             error = OT_ERROR_NONE;
    const otExtAddress *eui64Ptr;

    SuccessOrExit(error = ReadEui64(eui64Ptr));
    aEui64 = *eui64Ptr;

exit:
    return error;
}

otError SpinelDecoder::ReadEui48(spinel_eui48_t &aEui48)
{
    otError               error = OT_ERROR_NONE;
    const spinel_eui48_t *eui48Ptr;

    SuccessOrExit(error = ReadEui48(eui48Ptr));
    aEui48 = *eui48Ptr;

exit:
    return error;
}

otError SpinelDecoder::ReadUtf8(const char *&aUtf8)
{
    otError error = OT_ERROR_NONE;
    size_t  len;

    // Ensure there is at least one byte (for null character).
    VerifyOrExit(mIndex + sizeof(uint8_t) <= mEnd, error = OT_ERROR_PARSE);

    len = strnlen(reinterpret_cast<const char *>(&mFrame[mIndex]), mEnd - mIndex);
    VerifyOrExit(len < static_cast<uint16_t>(mEnd - mIndex), error = OT_ERROR_PARSE);

    aUtf8 = reinterpret_cast<const char *>(&mFrame[mIndex]);

    // `sizeof(uint8_t)` is added for the terminating null character.
    mIndex += static_cast<uint16_t>(len + sizeof(uint8_t));

exit:
    return error;
}

otError SpinelDecoder::ReadData(const uint8_t *&aData, uint16_t &aDataLen)
{
    aDataLen = mEnd - mIndex;

    return ReadItem(&aData, aDataLen);
}

otError SpinelDecoder::ReadDataWithLen(const uint8_t *&aData, uint16_t &aDataLen)
{
    otError  error = OT_ERROR_NONE;
    uint16_t len;

    SuccessOrExit(error = ReadUint16(len));
    SuccessOrExit(error = ReadItem(&aData, len));
    aDataLen = len;

exit:
    return error;
}

otError SpinelDecoder::OpenStruct(void)
{
    otError  error = OT_ERROR_NONE;
    uint16_t structLen;

    VerifyOrExit(mNumOpenStructs < kMaxNestedStructs, error = OT_ERROR_INVALID_STATE);

    SuccessOrExit(error = ReadUint16(structLen));
    VerifyOrExit(structLen <= mEnd - mIndex, error = OT_ERROR_PARSE);

    mPrevEnd[mNumOpenStructs] = mEnd;
    mEnd                      = (mIndex + structLen);
    mNumOpenStructs++;

exit:
    return error;
}

otError SpinelDecoder::CloseStruct(void)
{
    otError error = OT_ERROR_NONE;

    VerifyOrExit(mNumOpenStructs > 0, error = OT_ERROR_INVALID_STATE);

    // If there is a saved position and it is contained
    // within the current struct being closed, the saved
    // position is cleared to ensure user cannot go back
    // to middle of an already closed struct.

    if (IsSavedPositionValid() && (mNumOpenStructs == mSavedNumOpenStructs))
    {
        ClearSavedPosition();
    }

    mNumOpenStructs--;
    mIndex = mEnd;
    mEnd   = mPrevEnd[mNumOpenStructs];

exit:
    return error;
}

void SpinelDecoder::SavePosition(void)
{
    mSavedIndex          = mIndex;
    mSavedEnd            = mEnd;
    mSavedNumOpenStructs = mNumOpenStructs;
}

otError SpinelDecoder::ResetToSaved(void)
{
    otError error = OT_ERROR_NONE;

    VerifyOrExit(IsSavedPositionValid(), error = OT_ERROR_INVALID_STATE);

    mIndex          = mSavedIndex;
    mEnd            = mSavedEnd;
    mNumOpenStructs = mSavedNumOpenStructs;

exit:
    return error;
}

} // namespace Ncp
} // namespace ot
