/*
 *
 *    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 ApplicationStruct {
enum class Fields : uint8_t {
  kCatalogVendorID = 0,
  kApplicationID = 1,
};

struct Type {
public:
  uint16_t catalogVendorID = static_cast<uint16_t>(0);
  chip::CharSpan applicationID;

  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 ApplicationStruct
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 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;
  Optional<bool> metadataEnabled;
  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
