/*
 *
 *    Copyright (c) 2022 Project CHIP Authors
 *
 *    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.
 */

// THIS FILE IS GENERATED BY ZAP

#include <app/data-model/Decode.h>
#include <app/data-model/Encode.h>

#pragma once

namespace chip {

struct PairWithCodeCommand
{
    chip::NodeId nodeId;
    chip::CharSpan payload;
    Optional<bool> discoverOnce;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), nodeId));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(1), payload));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(2), discoverOnce));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, nodeId));
                break;
            case 1:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, payload));
                break;
            case 2:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, discoverOnce));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct UnpairCommand
{
    chip::NodeId nodeId;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), nodeId));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, nodeId));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct GetCommissionerNodeIdCommand
{

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct GetCommissionerNodeIdResponse
{
    chip::NodeId nodeId;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), nodeId));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, nodeId));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct WaitForMsCommand
{
    uint32_t ms;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), ms));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, ms));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct WaitForCommissioningCommand
{

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct WaitForCommissioneeCommand
{
    chip::NodeId nodeId;
    Optional<bool> expireExistingSession;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), nodeId));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(1), expireExistingSession));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, nodeId));
                break;
            case 1:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, expireExistingSession));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct WaitForMessageCommand
{
    Optional<chip::CharSpan> registerKey;
    chip::CharSpan message;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), registerKey));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(1), message));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, registerKey));
                break;
            case 1:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, message));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct FindCommissionableCommand
{

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct FindCommissionableByShortDiscriminatorCommand
{
    uint64_t value;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), value));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, value));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct FindCommissionableByLongDiscriminatorCommand
{
    uint64_t value;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), value));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, value));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct FindCommissionableByCommissioningModeCommand
{

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct FindCommissionableByVendorIdCommand
{
    uint64_t value;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), value));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, value));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct FindCommissionableByDeviceTypeCommand
{
    uint64_t value;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), value));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, value));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct FindCommissionableByNameCommand
{
    chip::CharSpan value;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), value));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, value));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct FindCommissionerCommand
{

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct FindCommissionerByVendorIdCommand
{
    uint64_t value;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), value));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, value));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct FindCommissionerByDeviceTypeCommand
{
    uint64_t value;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), value));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, value));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct DiscoveryCommandResponse
{
    chip::CharSpan hostName;
    chip::CharSpan instanceName;
    uint16_t longDiscriminator;
    uint8_t shortDiscriminator;
    uint16_t vendorId;
    uint16_t productId;
    uint8_t commissioningMode;
    uint32_t deviceType;
    chip::CharSpan deviceName;
    chip::ByteSpan rotatingId;
    uint64_t rotatingIdLen;
    uint16_t pairingHint;
    chip::CharSpan pairingInstruction;
    bool supportsTcp;
    uint8_t numIPs;
    uint16_t port;
    Optional<uint32_t> mrpRetryIntervalIdle;
    Optional<uint32_t> mrpRetryIntervalActive;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), hostName));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(1), instanceName));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(2), longDiscriminator));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(3), shortDiscriminator));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(4), vendorId));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(5), productId));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(6), commissioningMode));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(7), deviceType));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(8), deviceName));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(9), rotatingId));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(10), rotatingIdLen));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(11), pairingHint));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(12), pairingInstruction));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(13), supportsTcp));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(14), numIPs));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(15), port));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(16), mrpRetryIntervalIdle));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(17), mrpRetryIntervalActive));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, hostName));
                break;
            case 1:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, instanceName));
                break;
            case 2:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, longDiscriminator));
                break;
            case 3:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, shortDiscriminator));
                break;
            case 4:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, vendorId));
                break;
            case 5:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, productId));
                break;
            case 6:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, commissioningMode));
                break;
            case 7:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, deviceType));
                break;
            case 8:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, deviceName));
                break;
            case 9:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, rotatingId));
                break;
            case 10:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, rotatingIdLen));
                break;
            case 11:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, pairingHint));
                break;
            case 12:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, pairingInstruction));
                break;
            case 13:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, supportsTcp));
                break;
            case 14:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, numIPs));
                break;
            case 15:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, port));
                break;
            case 16:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, mrpRetryIntervalIdle));
                break;
            case 17:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, mrpRetryIntervalActive));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct LogCommand
{
    chip::CharSpan message;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), message));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, message));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct UserPromptCommand
{
    chip::CharSpan message;
    Optional<chip::CharSpan> expectedValue;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), message));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(1), expectedValue));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, message));
                break;
            case 1:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, expectedValue));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct StartCommand
{
    Optional<chip::CharSpan> registerKey;
    Optional<uint16_t> discriminator;
    Optional<uint16_t> port;
    Optional<chip::CharSpan> kvs;
    Optional<uint16_t> minCommissioningTimeout;
    Optional<chip::CharSpan> filepath;
    Optional<chip::CharSpan> otaDownloadPath;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), registerKey));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(1), discriminator));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(2), port));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(3), kvs));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(4), minCommissioningTimeout));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(5), filepath));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(6), otaDownloadPath));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, registerKey));
                break;
            case 1:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, discriminator));
                break;
            case 2:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, port));
                break;
            case 3:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, kvs));
                break;
            case 4:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, minCommissioningTimeout));
                break;
            case 5:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, filepath));
                break;
            case 6:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, otaDownloadPath));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct StopCommand
{
    Optional<chip::CharSpan> registerKey;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), registerKey));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, registerKey));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct RebootCommand
{
    Optional<chip::CharSpan> registerKey;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), registerKey));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, registerKey));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct FactoryResetCommand
{
    Optional<chip::CharSpan> registerKey;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), registerKey));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, registerKey));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct CreateOtaImageCommand
{
    chip::CharSpan otaImageFilePath;
    chip::CharSpan rawImageFilePath;
    chip::CharSpan rawImageContent;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), otaImageFilePath));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(1), rawImageFilePath));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(2), rawImageContent));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, otaImageFilePath));
                break;
            case 1:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, rawImageFilePath));
                break;
            case 2:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, rawImageContent));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

struct CompareFilesCommand
{
    chip::CharSpan file1;
    chip::CharSpan file2;

    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
    {
        chip::TLV::TLVType outer;
        ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(0), file1));
        ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::ContextTag(1), file2));
        ReturnErrorOnFailure(writer.EndContainer(outer));
        return CHIP_NO_ERROR;
    }

    CHIP_ERROR Decode(chip::TLV::TLVReader & reader)
    {
        CHIP_ERROR err = CHIP_NO_ERROR;
        chip::TLV::TLVType outer;
        VerifyOrReturnError(chip::TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
        ReturnErrorOnFailure(reader.EnterContainer(outer));

        while ((err = reader.Next()) == CHIP_NO_ERROR)
        {
            VerifyOrReturnError(chip::TLV::IsContextTag(reader.GetTag()), CHIP_ERROR_INVALID_TLV_TAG);
            switch (chip::TLV::TagNumFromTag(reader.GetTag()))
            {
            case 0:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, file1));
                break;
            case 1:
                ReturnErrorOnFailure(chip::app::DataModel::Decode(reader, file2));
                break;
            default:
                break;
            }
        }

        VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
        ReturnErrorOnFailure(reader.ExitContainer(outer));

        return CHIP_NO_ERROR;
    }
};

namespace app {
namespace Clusters {

namespace CommissionerCommands {
namespace Commands {
namespace PairWithCode {
using Type = struct PairWithCodeCommand;
}
namespace Unpair {
using Type = struct UnpairCommand;
}
namespace GetCommissionerNodeId {
using Type = struct GetCommissionerNodeIdCommand;
}
namespace GetCommissionerNodeIdResponse {
using DecodableType = struct GetCommissionerNodeIdResponse;
}
} // namespace Commands
} // namespace CommissionerCommands

namespace DelayCommands {
namespace Commands {
namespace WaitForMs {
using Type = struct WaitForMsCommand;
}
namespace WaitForCommissioning {
using Type = struct WaitForCommissioningCommand;
}
namespace WaitForCommissionee {
using Type = struct WaitForCommissioneeCommand;
}
namespace WaitForMessage {
using Type = struct WaitForMessageCommand;
}
} // namespace Commands
} // namespace DelayCommands

namespace DiscoveryCommands {
namespace Commands {
namespace FindCommissionable {
using Type = struct FindCommissionableCommand;
}
namespace FindCommissionableByShortDiscriminator {
using Type = struct FindCommissionableByShortDiscriminatorCommand;
}
namespace FindCommissionableByLongDiscriminator {
using Type = struct FindCommissionableByLongDiscriminatorCommand;
}
namespace FindCommissionableByCommissioningMode {
using Type = struct FindCommissionableByCommissioningModeCommand;
}
namespace FindCommissionableByVendorId {
using Type = struct FindCommissionableByVendorIdCommand;
}
namespace FindCommissionableByDeviceType {
using Type = struct FindCommissionableByDeviceTypeCommand;
}
namespace FindCommissionableByName {
using Type = struct FindCommissionableByNameCommand;
}
namespace FindCommissioner {
using Type = struct FindCommissionerCommand;
}
namespace FindCommissionerByVendorId {
using Type = struct FindCommissionerByVendorIdCommand;
}
namespace FindCommissionerByDeviceType {
using Type = struct FindCommissionerByDeviceTypeCommand;
}
namespace DiscoveryCommandResponse {
using DecodableType = struct DiscoveryCommandResponse;
}
} // namespace Commands
} // namespace DiscoveryCommands

namespace LogCommands {
namespace Commands {
namespace Log {
using Type = struct LogCommand;
}
namespace UserPrompt {
using Type = struct UserPromptCommand;
}
} // namespace Commands
} // namespace LogCommands

namespace SystemCommands {
namespace Commands {
namespace Start {
using Type = struct StartCommand;
}
namespace Stop {
using Type = struct StopCommand;
}
namespace Reboot {
using Type = struct RebootCommand;
}
namespace FactoryReset {
using Type = struct FactoryResetCommand;
}
namespace CreateOtaImage {
using Type = struct CreateOtaImageCommand;
}
namespace CompareFiles {
using Type = struct CompareFilesCommand;
}
} // namespace Commands
} // namespace SystemCommands

} // namespace Clusters
} // namespace app

} // namespace chip
