/*
 *  Copyright (c) 2016, 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 <stdint.h>
#include <stdio.h>

#include <openthread/ip6.h>
#include <openthread/platform/toolchain.h>

#include "test_util.h"
#include "thread/neighbor.hpp"

namespace ot {

extern "C" {
uint32_t       otNetifAddress_Size_c();
uint32_t       otNetifAddress_offset_mNext_c();
otNetifAddress CreateNetif_c();
}

void test_packed1(void)
{
    OT_TOOL_PACKED_BEGIN
    struct packed_t
    {
        uint8_t  mByte;
        uint32_t mWord;
        uint16_t mShort;
    } OT_TOOL_PACKED_END;

    static_assert(sizeof(packed_t) == 7, "packed_t should be packed to 7 bytes");

    VerifyOrQuit(sizeof(packed_t) == 7, "OT_TOOL_PACKED failed 1");
}

void test_packed2(void)
{
    OT_TOOL_PACKED_BEGIN
    struct packed_t
    {
        uint8_t mBytes[3];
        uint8_t mByte;
    } OT_TOOL_PACKED_END;

    static_assert(sizeof(packed_t) == 4, "packed_t should be packed to 4 bytes");

    VerifyOrQuit(sizeof(packed_t) == 4, "OT_TOOL_PACKED failed 2");
}

void test_packed_union(void)
{
    typedef struct
    {
        uint16_t mField;
    } nested_t;

    OT_TOOL_PACKED_BEGIN
    struct packed_t
    {
        uint8_t mBytes[3];
        union
        {
            nested_t mNestedStruct;
            uint8_t  mByte;
        } OT_TOOL_PACKED_FIELD;
    } OT_TOOL_PACKED_END;

    static_assert(sizeof(packed_t) == 5, "packed_t should be packed to 5 bytes");

    VerifyOrQuit(sizeof(packed_t) == 5, "OT_TOOL_PACKED failed 3");
}

void test_packed_enum(void)
{
    Neighbor neighbor;
    neighbor.SetState(Neighbor::kStateValid);

    // Make sure that when we read the 3 bit field it is read as unsigned, so it return '4'
    VerifyOrQuit(neighbor.GetState() == Neighbor::kStateValid, "OT_TOOL_PACKED failed 4");
}

void test_addr_sizes(void)
{
    VerifyOrQuit(offsetof(otNetifAddress, mNext) == otNetifAddress_offset_mNext_c(),
                 "mNext should offset the same in C & C++");
    VerifyOrQuit(sizeof(otNetifAddress) == otNetifAddress_Size_c(), "otNetifAddress should the same in C & C++");
}

void test_addr_bitfield(void) { VerifyOrQuit(CreateNetif_c().mScopeOverrideValid == true, "test_addr_size_cpp"); }

void test_packed_alignment(void)
{
    OT_TOOL_PACKED_BEGIN
    struct PackedStruct
    {
        uint32_t mUint32;
        uint8_t  mByte;
        uint16_t mUint16;
    } OT_TOOL_PACKED_END;

    PackedStruct   packedStruct;
    PackedStruct   packedStructCopy;
    const uint8_t *packedStructBytes = reinterpret_cast<const uint8_t *>(&packedStruct);
    uint8_t        buffer[sizeof(PackedStruct) * 2 + 1];

    VerifyOrQuit(sizeof(PackedStruct) == 7, "OT_TOOL_PACKED failed");

    packedStruct.mUint32 = 0x12345678;
    packedStruct.mByte   = 0xfe;
    packedStruct.mUint16 = 0xabcd;

    for (size_t start = 0; start < sizeof(PackedStruct); start++)
    {
        uint8_t *ptr = &buffer[start];

        memset(buffer, 0, sizeof(buffer));

        *reinterpret_cast<PackedStruct *>(ptr) = packedStruct;

        for (size_t i = 0; i < start; i++)
        {
            VerifyOrQuit(buffer[i] == 0, "OT_TOOL_PACKED alignment failed - pre-size write");
        }

        VerifyOrQuit(memcmp(ptr, packedStructBytes, sizeof(PackedStruct)) == 0, "OT_TOOL_PACKED alignment failed");

        for (size_t i = start + sizeof(packedStruct); i < sizeof(buffer); i++)
        {
            VerifyOrQuit(buffer[i] == 0, "OT_TOOL_PACKED alignment failed - post-size write");
        }

        memset(&packedStructCopy, 0, sizeof(PackedStruct));
        packedStructCopy = *reinterpret_cast<PackedStruct *>(ptr);

        VerifyOrQuit(memcmp(&packedStructCopy, &packedStruct, sizeof(PackedStruct)) == 0,
                     "OT_TOOL_PACKED failed - read error");
    }
}

void TestToolchain(void)
{
    test_packed1();
    test_packed2();
    test_packed_union();
    test_packed_enum();
    test_addr_sizes();
    test_addr_bitfield();
    test_packed_alignment();
}

} // namespace ot

int main(void)
{
    ot::TestToolchain();
    printf("All tests passed\n");
    return 0;
}
