/*
 *
 *    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
// This file is generated from clusters-shared-Structs.h.zapt

#pragma once

#include <app/data-model/DecodableList.h>
#include <app/data-model/List.h>
#include <app/data-model/Nullable.h>
#include <lib/core/CHIPError.h>
#include <lib/core/DataModelTypes.h>
#include <lib/core/Optional.h>
#include <lib/core/TLV.h>
#include <lib/support/BitMask.h>

#include <clusters/shared/Enums.h>

#include <cstdint>

namespace chip {
namespace app {
namespace Clusters {

// Structs shared across multiple clusters.
namespace detail {
namespace Structs {

namespace ModeTagStruct {
enum class Fields : uint8_t
{
    kMfgCode = 0,
    kValue   = 1,
};

struct Type
{
public:
    Optional<chip::VendorId> mfgCode;
    uint16_t value = static_cast<uint16_t>(0);

    CHIP_ERROR Decode(TLV::TLVReader & reader);

    static constexpr bool kIsFabricScoped = false;

    CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const;
};

using DecodableType = Type;

} // namespace ModeTagStruct
namespace ModeOptionStruct {
enum class Fields : uint8_t
{
    kLabel    = 0,
    kMode     = 1,
    kModeTags = 2,
};

struct Type
{
public:
    chip::CharSpan label;
    uint8_t mode = static_cast<uint8_t>(0);
    DataModel::List<const Structs::ModeTagStruct::Type> modeTags;

    static constexpr bool kIsFabricScoped = false;

    CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const;
};

struct DecodableType
{
public:
    chip::CharSpan label;
    uint8_t mode = static_cast<uint8_t>(0);
    DataModel::DecodableList<Structs::ModeTagStruct::DecodableType> modeTags;

    CHIP_ERROR Decode(TLV::TLVReader & reader);

    static constexpr bool kIsFabricScoped = false;
};

} // namespace ModeOptionStruct
namespace MeasurementAccuracyRangeStruct {
enum class Fields : uint8_t
{
    kRangeMin       = 0,
    kRangeMax       = 1,
    kPercentMax     = 2,
    kPercentMin     = 3,
    kPercentTypical = 4,
    kFixedMax       = 5,
    kFixedMin       = 6,
    kFixedTypical   = 7,
};

struct Type
{
public:
    int64_t rangeMin = static_cast<int64_t>(0);
    int64_t rangeMax = static_cast<int64_t>(0);
    Optional<chip::Percent100ths> percentMax;
    Optional<chip::Percent100ths> percentMin;
    Optional<chip::Percent100ths> percentTypical;
    Optional<uint64_t> fixedMax;
    Optional<uint64_t> fixedMin;
    Optional<uint64_t> fixedTypical;

    CHIP_ERROR Decode(TLV::TLVReader & reader);

    static constexpr bool kIsFabricScoped = false;

    CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const;
};

using DecodableType = Type;

} // namespace MeasurementAccuracyRangeStruct
namespace MeasurementAccuracyStruct {
enum class Fields : uint8_t
{
    kMeasurementType  = 0,
    kMeasured         = 1,
    kMinMeasuredValue = 2,
    kMaxMeasuredValue = 3,
    kAccuracyRanges   = 4,
};

struct Type
{
public:
    MeasurementTypeEnum measurementType = static_cast<MeasurementTypeEnum>(0);
    bool measured                       = static_cast<bool>(0);
    int64_t minMeasuredValue            = static_cast<int64_t>(0);
    int64_t maxMeasuredValue            = static_cast<int64_t>(0);
    DataModel::List<const Structs::MeasurementAccuracyRangeStruct::Type> accuracyRanges;

    static constexpr bool kIsFabricScoped = false;

    CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const;
};

struct DecodableType
{
public:
    MeasurementTypeEnum measurementType = static_cast<MeasurementTypeEnum>(0);
    bool measured                       = static_cast<bool>(0);
    int64_t minMeasuredValue            = static_cast<int64_t>(0);
    int64_t maxMeasuredValue            = static_cast<int64_t>(0);
    DataModel::DecodableList<Structs::MeasurementAccuracyRangeStruct::DecodableType> accuracyRanges;

    CHIP_ERROR Decode(TLV::TLVReader & reader);

    static constexpr bool kIsFabricScoped = false;
};

} // namespace MeasurementAccuracyStruct
namespace ErrorStateStruct {
enum class Fields : uint8_t
{
    kErrorStateID      = 0,
    kErrorStateLabel   = 1,
    kErrorStateDetails = 2,
};

struct Type
{
public:
    uint8_t errorStateID = static_cast<uint8_t>(0);
    Optional<chip::CharSpan> errorStateLabel;
    Optional<chip::CharSpan> errorStateDetails;

    CHIP_ERROR Decode(TLV::TLVReader & reader);

    static constexpr bool kIsFabricScoped = false;

    CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const;
};

using DecodableType = Type;

} // namespace ErrorStateStruct
namespace LabelStruct {
enum class Fields : uint8_t
{
    kLabel = 0,
    kValue = 1,
};

struct Type
{
public:
    chip::CharSpan label;
    chip::CharSpan value;

    CHIP_ERROR Decode(TLV::TLVReader & reader);

    static constexpr bool kIsFabricScoped = false;

    CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const;
};

using DecodableType = Type;

} // namespace LabelStruct
namespace OperationalStateStruct {
enum class Fields : uint8_t
{
    kOperationalStateID    = 0,
    kOperationalStateLabel = 1,
};

struct Type
{
public:
    uint8_t operationalStateID = static_cast<uint8_t>(0);
    Optional<chip::CharSpan> operationalStateLabel;

    CHIP_ERROR Decode(TLV::TLVReader & reader);

    static constexpr bool kIsFabricScoped = false;

    CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const;
};

using DecodableType = Type;

} // namespace OperationalStateStruct
} // namespace Structs
} // namespace detail

// Global structs.
namespace Globals {
namespace Structs {

namespace CurrencyStruct {
enum class Fields : uint8_t
{
    kCurrency      = 0,
    kDecimalPoints = 1,
};

struct Type
{
public:
    uint16_t currency     = static_cast<uint16_t>(0);
    uint8_t decimalPoints = static_cast<uint8_t>(0);

    CHIP_ERROR Decode(TLV::TLVReader & reader);

    static constexpr bool kIsFabricScoped = false;

    CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const;
};

using DecodableType = Type;

} // namespace CurrencyStruct

namespace PriceStruct {
enum class Fields : uint8_t
{
    kAmount   = 0,
    kCurrency = 1,
};

struct Type
{
public:
    int64_t amount = static_cast<int64_t>(0);
    Globals::Structs::CurrencyStruct::Type currency;

    CHIP_ERROR Decode(TLV::TLVReader & reader);

    static constexpr bool kIsFabricScoped = false;

    CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const;
};

using DecodableType = Type;

} // namespace PriceStruct

namespace MeasurementAccuracyRangeStruct {
enum class Fields : uint8_t
{
    kRangeMin       = 0,
    kRangeMax       = 1,
    kPercentMax     = 2,
    kPercentMin     = 3,
    kPercentTypical = 4,
    kFixedMax       = 5,
    kFixedMin       = 6,
    kFixedTypical   = 7,
};

struct Type
{
public:
    int64_t rangeMin = static_cast<int64_t>(0);
    int64_t rangeMax = static_cast<int64_t>(0);
    Optional<chip::Percent100ths> percentMax;
    Optional<chip::Percent100ths> percentMin;
    Optional<chip::Percent100ths> percentTypical;
    Optional<uint64_t> fixedMax;
    Optional<uint64_t> fixedMin;
    Optional<uint64_t> fixedTypical;

    CHIP_ERROR Decode(TLV::TLVReader & reader);

    static constexpr bool kIsFabricScoped = false;

    CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const;
};

using DecodableType = Type;

} // namespace MeasurementAccuracyRangeStruct

namespace MeasurementAccuracyStruct {
enum class Fields : uint8_t
{
    kMeasurementType  = 0,
    kMeasured         = 1,
    kMinMeasuredValue = 2,
    kMaxMeasuredValue = 3,
    kAccuracyRanges   = 4,
};

struct Type
{
public:
    Globals::MeasurementTypeEnum measurementType = static_cast<Globals::MeasurementTypeEnum>(0);
    bool measured                                = static_cast<bool>(0);
    int64_t minMeasuredValue                     = static_cast<int64_t>(0);
    int64_t maxMeasuredValue                     = static_cast<int64_t>(0);
    DataModel::List<const Globals::Structs::MeasurementAccuracyRangeStruct::Type> accuracyRanges;

    static constexpr bool kIsFabricScoped = false;

    CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const;
};

struct DecodableType
{
public:
    Globals::MeasurementTypeEnum measurementType = static_cast<Globals::MeasurementTypeEnum>(0);
    bool measured                                = static_cast<bool>(0);
    int64_t minMeasuredValue                     = static_cast<int64_t>(0);
    int64_t maxMeasuredValue                     = static_cast<int64_t>(0);
    DataModel::DecodableList<Globals::Structs::MeasurementAccuracyRangeStruct::DecodableType> accuracyRanges;

    CHIP_ERROR Decode(TLV::TLVReader & reader);

    static constexpr bool kIsFabricScoped = false;
};

} // namespace MeasurementAccuracyStruct

namespace AtomicAttributeStatusStruct {
enum class Fields : uint8_t
{
    kAttributeID = 0,
    kStatusCode  = 1,
};

struct Type
{
public:
    chip::AttributeId attributeID = static_cast<chip::AttributeId>(0);
    uint8_t statusCode            = static_cast<uint8_t>(0);

    CHIP_ERROR Decode(TLV::TLVReader & reader);

    static constexpr bool kIsFabricScoped = false;

    CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const;
};

using DecodableType = Type;

} // namespace AtomicAttributeStatusStruct

namespace ICECandidateStruct {
enum class Fields : uint8_t
{
    kCandidate     = 0,
    kSDPMid        = 1,
    kSDPMLineIndex = 2,
};

struct Type
{
public:
    chip::CharSpan candidate;
    DataModel::Nullable<chip::CharSpan> SDPMid;
    DataModel::Nullable<uint16_t> SDPMLineIndex;

    CHIP_ERROR Decode(TLV::TLVReader & reader);

    static constexpr bool kIsFabricScoped = false;

    CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const;
};

using DecodableType = Type;

} // namespace ICECandidateStruct

namespace ICEServerStruct {
enum class Fields : uint8_t
{
    kURLs       = 0,
    kUsername   = 1,
    kCredential = 2,
    kCaid       = 3,
};

struct Type
{
public:
    DataModel::List<const chip::CharSpan> URLs;
    Optional<chip::CharSpan> username;
    Optional<chip::CharSpan> credential;
    Optional<uint16_t> caid;

    static constexpr bool kIsFabricScoped = false;

    CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const;
};

struct DecodableType
{
public:
    DataModel::DecodableList<chip::CharSpan> URLs;
    Optional<chip::CharSpan> username;
    Optional<chip::CharSpan> credential;
    Optional<uint16_t> caid;

    CHIP_ERROR Decode(TLV::TLVReader & reader);

    static constexpr bool kIsFabricScoped = false;
};

} // namespace ICEServerStruct

namespace LocationDescriptorStruct {
enum class Fields : uint8_t
{
    kLocationName = 0,
    kFloorNumber  = 1,
    kAreaType     = 2,
};

struct Type
{
public:
    chip::CharSpan locationName;
    DataModel::Nullable<int16_t> floorNumber;
    DataModel::Nullable<Globals::AreaTypeTag> areaType;

    CHIP_ERROR Decode(TLV::TLVReader & reader);

    static constexpr bool kIsFabricScoped = false;

    CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const;
};

using DecodableType = Type;

} // namespace LocationDescriptorStruct

namespace PowerThresholdStruct {
enum class Fields : uint8_t
{
    kPowerThreshold         = 0,
    kApparentPowerThreshold = 1,
    kPowerThresholdSource   = 2,
};

struct Type
{
public:
    Optional<int64_t> powerThreshold;
    Optional<int64_t> apparentPowerThreshold;
    DataModel::Nullable<Globals::PowerThresholdSourceEnum> powerThresholdSource;

    CHIP_ERROR Decode(TLV::TLVReader & reader);

    static constexpr bool kIsFabricScoped = false;

    CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const;
};

using DecodableType = Type;

} // namespace PowerThresholdStruct

namespace SemanticTagStruct {
enum class Fields : uint8_t
{
    kMfgCode     = 0,
    kNamespaceID = 1,
    kTag         = 2,
    kLabel       = 3,
};

struct Type
{
public:
    DataModel::Nullable<chip::VendorId> mfgCode;
    uint8_t namespaceID = static_cast<uint8_t>(0);
    uint8_t tag         = static_cast<uint8_t>(0);
    Optional<DataModel::Nullable<chip::CharSpan>> label;

    CHIP_ERROR Decode(TLV::TLVReader & reader);

    static constexpr bool kIsFabricScoped = false;

    CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const;
};

using DecodableType = Type;

} // namespace SemanticTagStruct

namespace TestGlobalStruct {
enum class Fields : uint8_t
{
    kName     = 0,
    kMyBitmap = 1,
    kMyEnum   = 2,
};

struct Type
{
public:
    chip::CharSpan name;
    DataModel::Nullable<chip::BitMask<Globals::TestGlobalBitmap>> myBitmap;
    Optional<DataModel::Nullable<Globals::TestGlobalEnum>> myEnum;

    CHIP_ERROR Decode(TLV::TLVReader & reader);

    static constexpr bool kIsFabricScoped = false;

    CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const;
};

using DecodableType = Type;

} // namespace TestGlobalStruct

namespace ViewportStruct {
enum class Fields : uint8_t
{
    kX1 = 0,
    kY1 = 1,
    kX2 = 2,
    kY2 = 3,
};

struct Type
{
public:
    uint16_t x1 = static_cast<uint16_t>(0);
    uint16_t y1 = static_cast<uint16_t>(0);
    uint16_t x2 = static_cast<uint16_t>(0);
    uint16_t y2 = static_cast<uint16_t>(0);

    CHIP_ERROR Decode(TLV::TLVReader & reader);

    static constexpr bool kIsFabricScoped = false;

    CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const;
};

using DecodableType = Type;

} // namespace ViewportStruct

namespace WebRTCSessionStruct {
enum class Fields : uint8_t
{
    kId              = 0,
    kPeerNodeID      = 1,
    kPeerEndpointID  = 2,
    kStreamUsage     = 3,
    kVideoStreamID   = 4,
    kAudioStreamID   = 5,
    kMetadataEnabled = 6,
    kFabricIndex     = 254,
};

struct Type
{
public:
    uint16_t id                          = static_cast<uint16_t>(0);
    chip::NodeId peerNodeID              = static_cast<chip::NodeId>(0);
    chip::EndpointId peerEndpointID      = static_cast<chip::EndpointId>(0);
    Globals::StreamUsageEnum streamUsage = static_cast<Globals::StreamUsageEnum>(0);
    DataModel::Nullable<uint16_t> videoStreamID;
    DataModel::Nullable<uint16_t> audioStreamID;
    bool metadataEnabled          = static_cast<bool>(0);
    chip::FabricIndex fabricIndex = static_cast<chip::FabricIndex>(0);

    CHIP_ERROR Decode(TLV::TLVReader & reader);

    static constexpr bool kIsFabricScoped = true;

    auto GetFabricIndex() const { return fabricIndex; }

    void SetFabricIndex(chip::FabricIndex fabricIndex_) { fabricIndex = fabricIndex_; }

    CHIP_ERROR EncodeForWrite(TLV::TLVWriter & aWriter, TLV::Tag aTag) const;
    CHIP_ERROR EncodeForRead(TLV::TLVWriter & aWriter, TLV::Tag aTag, FabricIndex aAccessingFabricIndex) const;

private:
    CHIP_ERROR DoEncode(TLV::TLVWriter & aWriter, TLV::Tag aTag, const Optional<FabricIndex> & aAccessingFabricIndex) const;
};

using DecodableType = Type;

} // namespace WebRTCSessionStruct

} // namespace Structs
} // namespace Globals
} // namespace Clusters
} // namespace app
} // namespace chip
