/*
 *
 *    Copyright (c) 2021 Project CHIP Authors
 *    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 <app-common/zap-generated/cluster-objects.h>
#include <app/data-model/Decode.h>
#include <app/data-model/Encode.h>
#include <lib/core/TLV.h>
#include <lib/support/CHIPMem.h>
#include <system/SystemPacketBuffer.h>
#include <system/TLVPacketBufferBackingStore.h>

#include <lib/core/StringBuilderAdapters.h>
#include <lib/support/tests/ExtraPwTestMacros.h>
#include <pw_unit_test/framework.h>

namespace {

using namespace chip;
using namespace chip::app;
using namespace chip::app::Clusters;

class TestDataModelSerialization : public ::testing::Test
{
public:
    static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); }
    static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); }
    void TearDown() override { System::PacketBufferHandle buf = mStore.Release(); }

    // Helper functions
    template <typename Encodable, typename Decodable>
    void NullablesOptionalsEncodeDecodeCheck(bool encodeNulls, bool encodeValues);

    template <typename Encodable, typename Decodable>
    void NullablesOptionalsEncodeDecodeCheck();

    void SetupBuf();
    void DumpBuf();
    void SetupReader();

    System::TLVPacketBufferBackingStore mStore;
    TLV::TLVWriter mWriter;
    TLV::TLVReader mReader;
};

using namespace TLV;

void TestDataModelSerialization::SetupBuf()
{
    System::PacketBufferHandle buf;

    buf = System::PacketBufferHandle::New(1024);
    mStore.Init(std::move(buf));

    EXPECT_SUCCESS(mWriter.Init(mStore));
    EXPECT_SUCCESS(mReader.Init(mStore));
}

void TestDataModelSerialization::DumpBuf()
{
    TLV::TLVReader reader;
    EXPECT_SUCCESS(reader.Init(mStore));

    //
    // Enable this once the TLV pretty printer has been checked in.
    //
#if defined(ENABLE_TLV_PRINT_OUT) && ENABLE_TLV_PRINT_OUT
    TLV::Debug::Print(reader);
#endif
}

void TestDataModelSerialization::SetupReader()
{

    EXPECT_SUCCESS(mReader.Init(mStore));
    EXPECT_EQ(mReader.Next(), CHIP_NO_ERROR);
}

template <typename T>
struct TagValuePair
{
    TLV::Tag tag;
    T & value;
};

template <typename T>
TagValuePair<T> MakeTagValuePair(TLV::Tag tag, T & value)
{
    return TagValuePair<T>{ tag, value };
}

template <typename... ArgTypes>
CHIP_ERROR EncodeStruct(TLV::TLVWriter & writer, TLV::Tag tag, ArgTypes... Args)
{
    using expand_type = int[];
    TLV::TLVType type;

    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, type));
    (void) (expand_type{ (TEMPORARY_RETURN_IGNORED DataModel::Encode(writer, Args.tag, Args.value), 0)... });
    ReturnErrorOnFailure(writer.EndContainer(type));

    return CHIP_NO_ERROR;
}

bool StringMatches(Span<const char> str1, const char * str2)
{
    if (str1.data() == nullptr || str2 == nullptr)
    {
        return false;
    }

    if (str1.size() != strlen(str2))
    {
        return false;
    }

    return (strncmp(str1.data(), str2, str1.size()) == 0);
}

TEST_F(TestDataModelSerialization, EncAndDecSimpleStruct)
{
    SetupBuf();

    //
    // Encode
    //
    {
        Clusters::UnitTesting::Structs::SimpleStruct::Type t;
        uint8_t buf[4]  = { 0, 1, 2, 3 };
        char strbuf[10] = "chip";

        t.a = 20;
        t.b = true;
        t.c = Clusters::UnitTesting::SimpleEnum::kValueA;
        t.d = buf;

        t.e = Span<char>{ strbuf, strlen(strbuf) };

        t.f.Set(Clusters::UnitTesting::SimpleBitmap::kValueC);

        EXPECT_EQ(DataModel::Encode(mWriter, TLV::AnonymousTag(), t), CHIP_NO_ERROR);

        EXPECT_EQ(mWriter.Finalize(), CHIP_NO_ERROR);

        DumpBuf();
    }

    //
    // Decode
    //
    {
        Clusters::UnitTesting::Structs::SimpleStruct::Type t;

        SetupReader();

        EXPECT_EQ(DataModel::Decode(mReader, t), CHIP_NO_ERROR);

        EXPECT_EQ(t.a, 20);
        EXPECT_TRUE(t.b);
        EXPECT_EQ(t.c, Clusters::UnitTesting::SimpleEnum::kValueA);

        EXPECT_EQ(t.d.size(), 4u);

        for (uint32_t i = 0; i < t.d.size(); i++)
        {
            EXPECT_EQ(t.d.data()[i], i);
        }

        EXPECT_TRUE(StringMatches(t.e, "chip"));
        EXPECT_TRUE(t.f.HasOnly(Clusters::UnitTesting::SimpleBitmap::kValueC));
    }
}

TEST_F(TestDataModelSerialization, EncAndDecSimpleStructNegativeEnum)

{

    SetupBuf();

    //
    // Encode
    //
    {
        Clusters::UnitTesting::Structs::SimpleStruct::Type t;
        uint8_t buf[4]  = { 0, 1, 2, 3 };
        char strbuf[10] = "chip";

        t.a = 20;
        t.b = true;
        t.c = static_cast<Clusters::UnitTesting::SimpleEnum>(10);
        t.d = buf;

        t.e = Span<char>{ strbuf, strlen(strbuf) };

        t.f.Set(Clusters::UnitTesting::SimpleBitmap::kValueC);

        EXPECT_EQ(DataModel::Encode(mWriter, TLV::AnonymousTag(), t), CHIP_NO_ERROR);

        EXPECT_EQ(mWriter.Finalize(), CHIP_NO_ERROR);

        DumpBuf();
    }

    //
    // Decode
    //
    {
        Clusters::UnitTesting::Structs::SimpleStruct::Type t;

        SetupReader();

        EXPECT_EQ(DataModel::Decode(mReader, t), CHIP_NO_ERROR);
        EXPECT_EQ(to_underlying(t.c), 4);
    }
}

TEST_F(TestDataModelSerialization, EncAndDecNestedStruct)
{

    SetupBuf();

    //
    // Encode
    //
    {
        Clusters::UnitTesting::Structs::NestedStruct::Type t;
        uint8_t buf[4]  = { 0, 1, 2, 3 };
        char strbuf[10] = "chip";

        t.a   = 20;
        t.b   = true;
        t.c.a = 11;
        t.c.b = true;
        t.c.c = Clusters::UnitTesting::SimpleEnum::kValueB;
        t.c.d = buf;

        t.c.e = Span<char>{ strbuf, strlen(strbuf) };

        EXPECT_EQ(DataModel::Encode(mWriter, TLV::AnonymousTag(), t), CHIP_NO_ERROR);
        EXPECT_EQ(mWriter.Finalize(), CHIP_NO_ERROR);

        DumpBuf();
    }

    //
    // Decode
    //
    {
        Clusters::UnitTesting::Structs::NestedStruct::DecodableType t;

        SetupReader();

        EXPECT_EQ(DataModel::Decode(mReader, t), CHIP_NO_ERROR);

        EXPECT_EQ(t.a, 20);
        EXPECT_TRUE(t.b);
        EXPECT_EQ(t.c.a, 11);
        EXPECT_TRUE(t.c.b);
        EXPECT_EQ(t.c.c, Clusters::UnitTesting::SimpleEnum::kValueB);

        EXPECT_EQ(t.c.d.size(), 4u);

        for (uint32_t i = 0; i < t.c.d.size(); i++)
        {
            EXPECT_EQ(t.c.d.data()[i], i);
        }

        EXPECT_TRUE(StringMatches(t.c.e, "chip"));
    }
}
TEST_F(TestDataModelSerialization, EncAndDecDecodableNestedStructList)
{

    SetupBuf();

    //
    // Encode
    //
    {
        Clusters::UnitTesting::Structs::NestedStructList::Type t;
        uint8_t buf[4]     = { 0, 1, 2, 3 };
        uint32_t intBuf[4] = { 10000, 10001, 10002, 10003 };
        char strbuf[10]    = "chip";
        Clusters::UnitTesting::Structs::SimpleStruct::Type structList[4];
        uint8_t i = 0;
        ByteSpan spanList[4];

        t.a   = 20;
        t.b   = true;
        t.c.a = 11;
        t.c.b = true;
        t.c.c = Clusters::UnitTesting::SimpleEnum::kValueB;
        t.c.d = buf;
        t.e   = intBuf;

        for (auto & item : structList)
        {
            item.a = i;
            item.b = true;
            i++;
        }

        t.f = spanList;

        spanList[0] = buf;
        spanList[1] = buf;
        spanList[2] = buf;
        spanList[3] = buf;

        t.g = buf;

        t.c.e = Span<char>{ strbuf, strlen(strbuf) };
        t.d   = structList;

        EXPECT_EQ(DataModel::Encode(mWriter, TLV::AnonymousTag(), t), CHIP_NO_ERROR);
        EXPECT_EQ(mWriter.Finalize(), CHIP_NO_ERROR);

        DumpBuf();
    }

    //
    // Decode
    //
    {
        Clusters::UnitTesting::Structs::NestedStructList::DecodableType t;
        int i;

        SetupReader();

        EXPECT_EQ(DataModel::Decode(mReader, t), CHIP_NO_ERROR);

        EXPECT_EQ(t.a, 20);
        EXPECT_TRUE(t.b);
        EXPECT_EQ(t.c.a, 11);
        EXPECT_TRUE(t.c.b);
        EXPECT_EQ(t.c.c, Clusters::UnitTesting::SimpleEnum::kValueB);

        EXPECT_TRUE(StringMatches(t.c.e, "chip"));

        {
            i         = 0;
            auto iter = t.d.begin();
            while (iter.Next())
            {
                auto & item = iter.GetValue();
                EXPECT_EQ(item.a, static_cast<uint8_t>(i));
                EXPECT_TRUE(item.b);
                i++;
            }

            EXPECT_EQ(iter.GetStatus(), CHIP_NO_ERROR);
            EXPECT_EQ(i, 4);
        }

        {
            i         = 0;
            auto iter = t.e.begin();
            while (iter.Next())
            {
                auto & item = iter.GetValue();
                EXPECT_EQ(item, static_cast<uint32_t>(i + 10000));
                i++;
            }

            EXPECT_EQ(iter.GetStatus(), CHIP_NO_ERROR);
            EXPECT_EQ(i, 4);
        }

        {
            i         = 0;
            auto iter = t.f.begin();

            while (iter.Next())
            {
                auto & item = iter.GetValue();

                unsigned int j = 0;
                for (; j < item.size(); j++)
                {
                    EXPECT_EQ(item.data()[j], j);
                }

                EXPECT_EQ(j, 4u);
                i++;
            }

            EXPECT_EQ(iter.GetStatus(), CHIP_NO_ERROR);
            EXPECT_EQ(i, 4);
        }

        {
            i         = 0;
            auto iter = t.g.begin();

            while (iter.Next())
            {
                auto & item = iter.GetValue();
                EXPECT_EQ(item, i);
                i++;
            }

            EXPECT_EQ(iter.GetStatus(), CHIP_NO_ERROR);
            EXPECT_EQ(i, 4);
        }
    }
}
TEST_F(TestDataModelSerialization, EncAndDecDecodableDoubleNestedStructList)
{

    SetupBuf();

    //
    // Encode
    //
    {
        Clusters::UnitTesting::Structs::DoubleNestedStructList::Type t;
        Clusters::UnitTesting::Structs::NestedStructList::Type n[4];
        Clusters::UnitTesting::Structs::SimpleStruct::Type structList[4];
        uint8_t i;

        t.a = n;

        i = 0;
        for (auto & item : structList)
        {
            item.a = static_cast<uint8_t>(35 + i);
            i++;
        }

        for (auto & item : n)
        {
            item.d = structList;
        }

        EXPECT_EQ(DataModel::Encode(mWriter, TLV::AnonymousTag(), t), CHIP_NO_ERROR);
        EXPECT_EQ(mWriter.Finalize(), CHIP_NO_ERROR);

        DumpBuf();
    }

    //
    // Decode
    //
    {
        Clusters::UnitTesting::Structs::DoubleNestedStructList::DecodableType t;

        SetupReader();

        EXPECT_EQ(DataModel::Decode(mReader, t), CHIP_NO_ERROR);

        uint8_t i = 0;

        auto iter = t.a.begin();
        while (iter.Next())
        {
            auto & item     = iter.GetValue();
            auto nestedIter = item.d.begin();

            unsigned int j = 0;
            while (nestedIter.Next())
            {
                auto & nestedItem = nestedIter.GetValue();

                EXPECT_EQ(nestedItem.a, (static_cast<uint8_t>(35) + j));
                j++;
            }

            EXPECT_EQ(j, 4u);
            i++;
        }

        EXPECT_EQ(iter.GetStatus(), CHIP_NO_ERROR);
        EXPECT_EQ(i, 4u);
    }
}

TEST_F(TestDataModelSerialization, OptionalFields)
{

    SetupBuf();

    //
    // Encode
    //
    {
        Clusters::UnitTesting::Structs::SimpleStruct::Type t;
        uint8_t buf[4]  = { 0, 1, 2, 3 };
        char strbuf[10] = "chip";

        t.a = 20;
        t.b = true;
        t.c = Clusters::UnitTesting::SimpleEnum::kValueA;
        t.d = buf;

        t.e = Span<char>{ strbuf, strlen(strbuf) };

        // Encode every field manually except a.
        {
            EXPECT_EQ(
                EncodeStruct(mWriter, TLV::AnonymousTag(),
                             MakeTagValuePair(TLV::ContextTag(Clusters::UnitTesting::Structs::SimpleStruct::Fields::kB), t.b),
                             MakeTagValuePair(TLV::ContextTag(Clusters::UnitTesting::Structs::SimpleStruct::Fields::kC), t.c),
                             MakeTagValuePair(TLV::ContextTag(Clusters::UnitTesting::Structs::SimpleStruct::Fields::kD), t.d),
                             MakeTagValuePair(TLV::ContextTag(Clusters::UnitTesting::Structs::SimpleStruct::Fields::kE), t.e)),
                CHIP_NO_ERROR);
        }

        EXPECT_EQ(mWriter.Finalize(), CHIP_NO_ERROR);

        DumpBuf();
    }

    //
    // Decode
    //
    {
        Clusters::UnitTesting::Structs::SimpleStruct::DecodableType t;

        SetupReader();

        // Set the value of a to a specific value, and ensure it is not over-written after decode.
        t.a = 150;

        EXPECT_EQ(DataModel::Decode(mReader, t), CHIP_NO_ERROR);

        // Ensure that the decoder did not over-write the value set in the generated object
        EXPECT_EQ(t.a, 150);

        EXPECT_TRUE(t.b);
        EXPECT_EQ(t.c, Clusters::UnitTesting::SimpleEnum::kValueA);

        EXPECT_EQ(t.d.size(), 4u);

        for (uint32_t i = 0; i < t.d.size(); i++)
        {
            EXPECT_EQ(t.d.data()[i], i);
        }

        EXPECT_TRUE(StringMatches(t.e, "chip"));
    }
}

TEST_F(TestDataModelSerialization, ExtraField)
{
    SetupBuf();

    //
    // Encode
    //
    {
        Clusters::UnitTesting::Structs::SimpleStruct::Type t;
        uint8_t buf[4]  = { 0, 1, 2, 3 };
        char strbuf[10] = "chip";

        t.a = 20;
        t.b = true;
        t.c = Clusters::UnitTesting::SimpleEnum::kValueA;
        t.d = buf;

        t.e = Span<char>{ strbuf, strlen(strbuf) };

        // Encode every field + an extra field.
        {
            EXPECT_EQ(EncodeStruct(
                          mWriter, TLV::AnonymousTag(),
                          MakeTagValuePair(TLV::ContextTag(Clusters::UnitTesting::Structs::SimpleStruct::Fields::kA), t.a),
                          MakeTagValuePair(TLV::ContextTag(Clusters::UnitTesting::Structs::SimpleStruct::Fields::kB), t.b),
                          MakeTagValuePair(TLV::ContextTag(Clusters::UnitTesting::Structs::SimpleStruct::Fields::kC), t.c),
                          MakeTagValuePair(TLV::ContextTag(Clusters::UnitTesting::Structs::SimpleStruct::Fields::kD), t.d),
                          MakeTagValuePair(TLV::ContextTag(Clusters::UnitTesting::Structs::SimpleStruct::Fields::kE), t.e),
                          MakeTagValuePair(
                              TLV::ContextTag(to_underlying(Clusters::UnitTesting::Structs::SimpleStruct::Fields::kE) + 1), t.a)),
                      CHIP_NO_ERROR);
        }

        EXPECT_EQ(mWriter.Finalize(), CHIP_NO_ERROR);

        DumpBuf();
    }

    //
    // Decode
    //
    {
        Clusters::UnitTesting::Structs::SimpleStruct::DecodableType t;

        SetupReader();

        // Ensure successful decode despite the extra field.
        EXPECT_EQ(DataModel::Decode(mReader, t), CHIP_NO_ERROR);

        EXPECT_EQ(t.a, 20);
        EXPECT_TRUE(t.b);
        EXPECT_EQ(t.c, Clusters::UnitTesting::SimpleEnum::kValueA);

        EXPECT_EQ(t.d.size(), 4u);

        for (uint32_t i = 0; i < t.d.size(); i++)
        {
            EXPECT_EQ(t.d.data()[i], i);
        }

        EXPECT_TRUE(StringMatches(t.e, "chip"));
    }
}

TEST_F(TestDataModelSerialization, InvalidSimpleFieldTypes)
{
    SetupBuf();
    //
    // Case #1: Swap out field a (an integer) with a boolean.
    //
    {
        //
        // Encode
        //
        {
            Clusters::UnitTesting::Structs::SimpleStruct::Type t;
            uint8_t buf[4]  = { 0, 1, 2, 3 };
            char strbuf[10] = "chip";

            t.a = 20;
            t.b = true;
            t.c = Clusters::UnitTesting::SimpleEnum::kValueA;
            t.d = buf;

            t.e = Span<char>{ strbuf, strlen(strbuf) };

            // Encode every field manually except a.
            {
                EXPECT_EQ(
                    EncodeStruct(mWriter, TLV::AnonymousTag(),
                                 MakeTagValuePair(TLV::ContextTag(Clusters::UnitTesting::Structs::SimpleStruct::Fields::kA), t.b),
                                 MakeTagValuePair(TLV::ContextTag(Clusters::UnitTesting::Structs::SimpleStruct::Fields::kB), t.b),
                                 MakeTagValuePair(TLV::ContextTag(Clusters::UnitTesting::Structs::SimpleStruct::Fields::kC), t.c),
                                 MakeTagValuePair(TLV::ContextTag(Clusters::UnitTesting::Structs::SimpleStruct::Fields::kD), t.d),
                                 MakeTagValuePair(TLV::ContextTag(Clusters::UnitTesting::Structs::SimpleStruct::Fields::kE), t.e)),
                    CHIP_NO_ERROR);
            }

            EXPECT_EQ(mWriter.Finalize(), CHIP_NO_ERROR);
            DumpBuf();
        }
        //
        // Decode
        //
        {
            Clusters::UnitTesting::Structs::SimpleStruct::DecodableType t;

            SetupReader();

            EXPECT_NE(DataModel::Decode(mReader, t), CHIP_NO_ERROR);
        }
    }

    SetupBuf();
    //
    // Case #2: Swap out an octet string with a UTF-8 string.
    //
    {
        //
        // Encode
        //
        {
            Clusters::UnitTesting::Structs::SimpleStruct::Type t;
            uint8_t buf[4]  = { 0, 1, 2, 3 };
            char strbuf[10] = "chip";

            t.a = 20;
            t.b = true;
            t.c = Clusters::UnitTesting::SimpleEnum::kValueA;
            t.d = buf;

            t.e = Span<char>{ strbuf, strlen(strbuf) };

            // Encode every field manually except a.
            {
                EXPECT_EQ(
                    EncodeStruct(mWriter, TLV::AnonymousTag(),
                                 MakeTagValuePair(TLV::ContextTag(Clusters::UnitTesting::Structs::SimpleStruct::Fields::kA), t.a),
                                 MakeTagValuePair(TLV::ContextTag(Clusters::UnitTesting::Structs::SimpleStruct::Fields::kB), t.b),
                                 MakeTagValuePair(TLV::ContextTag(Clusters::UnitTesting::Structs::SimpleStruct::Fields::kC), t.c),
                                 MakeTagValuePair(TLV::ContextTag(Clusters::UnitTesting::Structs::SimpleStruct::Fields::kD), t.e),
                                 MakeTagValuePair(TLV::ContextTag(Clusters::UnitTesting::Structs::SimpleStruct::Fields::kE), t.e)),
                    CHIP_NO_ERROR);
            }

            EXPECT_EQ(mWriter.Finalize(), CHIP_NO_ERROR);

            DumpBuf();
        }

        //
        // Decode
        //
        {
            Clusters::UnitTesting::Structs::SimpleStruct::DecodableType t;

            SetupReader();

            EXPECT_NE(DataModel::Decode(mReader, t), CHIP_NO_ERROR);
        }
    }
}

TEST_F(TestDataModelSerialization, InvalidListType)
{
    SetupBuf();

    //
    // Encode
    //
    {
        Clusters::UnitTesting::Structs::NestedStructList::Type t;
        uint32_t intBuf[4] = { 10000, 10001, 10002, 10003 };

        t.e = intBuf;

        // Encode a list of integers for field d instead of a list of structs.
        {
            EXPECT_EQ(
                EncodeStruct(mWriter, TLV::AnonymousTag(),
                             MakeTagValuePair(TLV::ContextTag(Clusters::UnitTesting::Structs::NestedStructList::Fields::kD), t.e)),
                CHIP_NO_ERROR);
        }

        EXPECT_EQ(mWriter.Finalize(), CHIP_NO_ERROR);
        DumpBuf();
    }

    //
    // Decode
    //
    {
        Clusters::UnitTesting::Structs::NestedStructList::DecodableType t;

        SetupReader();

        EXPECT_EQ(DataModel::Decode(mReader, t), CHIP_NO_ERROR);

        auto iter     = t.d.begin();
        bool hadItems = false;

        while (iter.Next())
        {
            hadItems = true;
        }

        EXPECT_NE(iter.GetStatus(), CHIP_NO_ERROR);
        EXPECT_FALSE(hadItems);
    }
}

namespace {
bool SimpleStructsEqual(const Clusters::UnitTesting::Structs::SimpleStruct::Type & s1,
                        const Clusters::UnitTesting::Structs::SimpleStruct::Type & s2)
{
    return s1.a == s2.a && s1.b == s2.b && s1.c == s2.c && s1.d.data_equal(s2.d) && s1.e.data_equal(s2.e) && s1.f == s2.f;
}

template <typename T>
bool ListsEqual(const DataModel::DecodableList<T> & list1, const DataModel::List<T> & list2)
{
    auto iter1 = list1.begin();
    auto iter2 = list2.begin();
    auto end2  = list2.end();
    while (iter1.Next())
    {
        if (iter2 == end2)
        {
            // list2 too small
            return false;
        }

        if (iter1.GetValue() != *iter2)
        {
            return false;
        }
        ++iter2;
    }
    if (iter1.GetStatus() != CHIP_NO_ERROR)
    {
        // Failed to decode
        return false;
    }
    if (iter2 != end2)
    {
        // list1 too small
        return false;
    }
    return true;
}

} // anonymous namespace

template <typename Encodable, typename Decodable>
void TestDataModelSerialization::NullablesOptionalsEncodeDecodeCheck(bool encodeNulls, bool encodeValues)
{

    SetupBuf();

    static const char structStr[] = "something";
    const uint8_t structBytes[]   = { 1, 8, 17 };
    Clusters::UnitTesting::Structs::SimpleStruct::Type myStruct;
    myStruct.a = 17;
    myStruct.b = true;
    myStruct.c = Clusters::UnitTesting::SimpleEnum::kValueB;
    myStruct.d = ByteSpan(structBytes);
    myStruct.e = CharSpan::fromCharString(structStr);
    myStruct.f = Clusters::UnitTesting::SimpleBitmap(2);

    Clusters::UnitTesting::SimpleEnum enumListVals[] = { Clusters::UnitTesting::SimpleEnum::kValueA,
                                                         Clusters::UnitTesting::SimpleEnum::kValueC };
    DataModel::List<Clusters::UnitTesting::SimpleEnum> enumList(enumListVals);

    // Encode
    {
        // str needs to live until we call DataModel::Encode.
        static const char str[] = "abc";
        CharSpan strSpan        = CharSpan::fromCharString(str);
        Encodable encodable;
        if (encodeNulls)
        {
            encodable.nullableInt.SetNull();
            encodable.nullableOptionalInt.Emplace().SetNull();

            encodable.nullableString.SetNull();
            encodable.nullableOptionalString.Emplace().SetNull();

            encodable.nullableStruct.SetNull();
            encodable.nullableOptionalStruct.Emplace().SetNull();

            encodable.nullableList.SetNull();
            encodable.nullableOptionalList.Emplace().SetNull();
        }
        else if (encodeValues)
        {
            encodable.nullableInt.SetNonNull(static_cast<uint16_t>(5u));
            encodable.optionalInt.Emplace(static_cast<uint16_t>(6u));
            encodable.nullableOptionalInt.Emplace().SetNonNull() = 7;

            encodable.nullableString.SetNonNull(strSpan);
            encodable.optionalString.Emplace() = strSpan;
            encodable.nullableOptionalString.Emplace().SetNonNull(strSpan);

            encodable.nullableStruct.SetNonNull(myStruct);
            encodable.optionalStruct.Emplace(myStruct);
            encodable.nullableOptionalStruct.Emplace().SetNonNull(myStruct);

            encodable.nullableList.SetNonNull() = enumList;
            encodable.optionalList.Emplace(enumList);
            encodable.nullableOptionalList.Emplace().SetNonNull(enumList);
        }
        else
        {
            // Just encode the non-optionals, as null.
            encodable.nullableInt.SetNull();
            encodable.nullableString.SetNull();
            encodable.nullableStruct.SetNull();
            encodable.nullableList.SetNull();
        }

        EXPECT_SUCCESS(DataModel::Encode(mWriter, TLV::AnonymousTag(), encodable));
        EXPECT_EQ(mWriter.Finalize(), CHIP_NO_ERROR);
    }

    // Decode
    {
        SetupReader();

        Decodable decodable;
        EXPECT_EQ(DataModel::Decode(mReader, decodable), CHIP_NO_ERROR);

        if (encodeNulls)
        {
            EXPECT_TRUE(decodable.nullableInt.IsNull());
            EXPECT_FALSE(decodable.optionalInt.HasValue());
            EXPECT_TRUE(decodable.nullableOptionalInt.HasValue());
            EXPECT_TRUE(decodable.nullableOptionalInt.Value().IsNull());

            EXPECT_TRUE(decodable.nullableString.IsNull());
            EXPECT_FALSE(decodable.optionalString.HasValue());
            EXPECT_TRUE(decodable.nullableOptionalString.HasValue());
            EXPECT_TRUE(decodable.nullableOptionalString.Value().IsNull());

            EXPECT_TRUE(decodable.nullableStruct.IsNull());
            EXPECT_FALSE(decodable.optionalStruct.HasValue());
            EXPECT_TRUE(decodable.nullableOptionalStruct.HasValue());
            EXPECT_TRUE(decodable.nullableOptionalStruct.Value().IsNull());

            EXPECT_TRUE(decodable.nullableList.IsNull());
            EXPECT_FALSE(decodable.optionalList.HasValue());
            EXPECT_TRUE(decodable.nullableOptionalList.HasValue());
            EXPECT_TRUE(decodable.nullableOptionalList.Value().IsNull());
        }
        else if (encodeValues)
        {
            static const char str[] = "abc";
            CharSpan strSpan        = CharSpan::fromCharString(str);

            EXPECT_FALSE(decodable.nullableInt.IsNull());
            EXPECT_EQ(decodable.nullableInt.Value(), 5);
            EXPECT_TRUE(decodable.optionalInt.HasValue());
            EXPECT_EQ(decodable.optionalInt.Value(), 6);
            EXPECT_TRUE(decodable.nullableOptionalInt.HasValue());
            EXPECT_FALSE(decodable.nullableOptionalInt.Value().IsNull());
            EXPECT_EQ(decodable.nullableOptionalInt.Value().Value(), 7);

            EXPECT_FALSE(decodable.nullableString.IsNull());
            EXPECT_TRUE(decodable.nullableString.Value().data_equal(strSpan));
            EXPECT_TRUE(decodable.optionalString.HasValue());
            EXPECT_TRUE(decodable.optionalString.Value().data_equal(strSpan));
            EXPECT_TRUE(decodable.nullableOptionalString.HasValue());
            EXPECT_FALSE(decodable.nullableOptionalString.Value().IsNull());
            EXPECT_TRUE(decodable.nullableOptionalString.Value().Value().data_equal(strSpan));

            EXPECT_FALSE(decodable.nullableStruct.IsNull());
            EXPECT_TRUE(SimpleStructsEqual(decodable.nullableStruct.Value(), myStruct));
            EXPECT_TRUE(decodable.optionalStruct.HasValue());
            EXPECT_TRUE(SimpleStructsEqual(decodable.optionalStruct.Value(), myStruct));
            EXPECT_TRUE(decodable.nullableOptionalStruct.HasValue());
            EXPECT_FALSE(decodable.nullableOptionalStruct.Value().IsNull());
            EXPECT_TRUE(SimpleStructsEqual(decodable.nullableOptionalStruct.Value().Value(), myStruct));

            EXPECT_FALSE(decodable.nullableList.IsNull());
            EXPECT_TRUE(ListsEqual(decodable.nullableList.Value(), enumList));
            EXPECT_TRUE(decodable.optionalList.HasValue());
            EXPECT_TRUE(ListsEqual(decodable.optionalList.Value(), enumList));
            EXPECT_TRUE(decodable.nullableOptionalList.HasValue());
            EXPECT_FALSE(decodable.nullableOptionalList.Value().IsNull());
            EXPECT_TRUE(ListsEqual(decodable.nullableOptionalList.Value().Value(), enumList));
        }
        else
        {
            EXPECT_TRUE(decodable.nullableInt.IsNull());
            EXPECT_FALSE(decodable.optionalInt.HasValue());
            EXPECT_FALSE(decodable.nullableOptionalInt.HasValue());

            EXPECT_TRUE(decodable.nullableString.IsNull());
            EXPECT_FALSE(decodable.optionalString.HasValue());
            EXPECT_FALSE(decodable.nullableOptionalString.HasValue());

            EXPECT_TRUE(decodable.nullableStruct.IsNull());
            EXPECT_FALSE(decodable.optionalStruct.HasValue());
            EXPECT_FALSE(decodable.nullableOptionalStruct.HasValue());

            EXPECT_TRUE(decodable.nullableList.IsNull());
            EXPECT_FALSE(decodable.optionalList.HasValue());
            EXPECT_FALSE(decodable.nullableOptionalList.HasValue());
        }
    }
}

template <typename Encodable, typename Decodable>
void TestDataModelSerialization::NullablesOptionalsEncodeDecodeCheck()
{
    NullablesOptionalsEncodeDecodeCheck<Encodable, Decodable>(false, false);
    NullablesOptionalsEncodeDecodeCheck<Encodable, Decodable>(true, false);
    NullablesOptionalsEncodeDecodeCheck<Encodable, Decodable>(false, true);
}

TEST_F(TestDataModelSerialization, NullablesOptionalsStruct)
{
    using EncType = Clusters::UnitTesting::Structs::NullablesAndOptionalsStruct::Type;
    using DecType = Clusters::UnitTesting::Structs::NullablesAndOptionalsStruct::DecodableType;
    NullablesOptionalsEncodeDecodeCheck<EncType, DecType>();
}

TEST_F(TestDataModelSerialization, NullablesOptionalsCommand)
{
    using EncType = Clusters::UnitTesting::Commands::TestComplexNullableOptionalRequest::Type;
    using DecType = Clusters::UnitTesting::Commands::TestComplexNullableOptionalRequest::DecodableType;
    NullablesOptionalsEncodeDecodeCheck<EncType, DecType>();
}

} // namespace
