{{> header}}

#include <app-common/zap-generated/cluster-objects.h>

namespace chip {
namespace app {
namespace Clusters {

namespace detail {
// Structs shared across multiple clusters.
namespace Structs {
{{#zcl_structs}}
{{#if has_more_than_one_cluster}}
{{> cluster_objects_struct header=false}}
{{/if}}
{{/zcl_structs}}
} // namespace Structs
} // namespace detail

{{#zcl_clusters}}
namespace {{asUpperCamelCase name}} {
{{#zcl_structs}}
{{#first}}
namespace Structs {
{{/first}}
{{#unless has_more_than_one_cluster}}
{{> cluster_objects_struct header=false}}
{{/unless}}
{{#last}}
} // namespace Structs
{{/last}}
{{/zcl_structs}}

namespace Commands {
{{#zcl_commands}}
namespace {{asUpperCamelCase name}} {
CHIP_ERROR Type::Encode(TLV::TLVWriter &writer, TLV::Tag tag) const{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    {{#zcl_command_arguments}}
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::k{{asUpperCamelCase label}})), {{asLowerCamelCase label}}));
    {{/zcl_command_arguments}}
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader &reader) {
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR) {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
            {{#zcl_command_arguments}}
            case to_underlying(Fields::k{{asUpperCamelCase label}}):
                ReturnErrorOnFailure(DataModel::Decode(reader, {{asLowerCamelCase label}}));
                break;
                {{/zcl_command_arguments}}
            default:
                break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace {{asUpperCamelCase name}}.
{{/zcl_commands}}
} // namespace Commands

namespace Attributes {
CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader &reader, const ConcreteAttributePath &path) {
    switch (path.mAttributeId)
    {
{{#zcl_attributes_server}}
    case Attributes::{{asUpperCamelCase label}}::TypeInfo::GetAttributeId():
        ReturnErrorOnFailure(DataModel::Decode(reader, {{asLowerCamelCase label}}));
        break;
{{/zcl_attributes_server}}
    default:
        break;
    }

    return CHIP_NO_ERROR;
}
} // namespace Attributes

namespace Events {
{{#zcl_events}}
namespace {{asUpperCamelCase name}} {
CHIP_ERROR Type::Encode(TLV::TLVWriter &writer, TLV::Tag tag) const{
    TLV::TLVType outer;
    ReturnErrorOnFailure(writer.StartContainer(tag, TLV::kTLVType_Structure, outer));
    {{#zcl_event_fields}}
    {{#if_is_fabric_scoped_struct type}}
    ReturnErrorOnFailure(DataModel::EncodeForRead(writer, TLV::ContextTag(to_underlying(Fields::k{{asUpperCamelCase name}})), GetFabricIndex(), {{asLowerCamelCase name}}));
    {{else}}
    ReturnErrorOnFailure(DataModel::Encode(writer, TLV::ContextTag(to_underlying(Fields::k{{asUpperCamelCase name}})), {{asLowerCamelCase name}}));
    {{/if_is_fabric_scoped_struct}}
    {{/zcl_event_fields}}
    ReturnErrorOnFailure(writer.EndContainer(outer));
    return CHIP_NO_ERROR;
}

CHIP_ERROR DecodableType::Decode(TLV::TLVReader &reader) {
    CHIP_ERROR err = CHIP_NO_ERROR;
    TLV::TLVType outer;
    VerifyOrReturnError(TLV::kTLVType_Structure == reader.GetType(), CHIP_ERROR_WRONG_TLV_TYPE);
    ReturnErrorOnFailure(reader.EnterContainer(outer));
    while ((err = reader.Next()) == CHIP_NO_ERROR) {
        if (!TLV::IsContextTag(reader.GetTag()))
        {
            continue;
        }
        switch (TLV::TagNumFromTag(reader.GetTag()))
        {
            {{#zcl_event_fields}}
        case to_underlying(Fields::k{{asUpperCamelCase name}}):
            ReturnErrorOnFailure(DataModel::Decode(reader, {{asLowerCamelCase name}}));
            break;
            {{/zcl_event_fields}}
        default:
            break;
        }
    }

    VerifyOrReturnError(err == CHIP_END_OF_TLV, err);
    ReturnErrorOnFailure(reader.ExitContainer(outer));
    return CHIP_NO_ERROR;
}
} // namespace {{asUpperCamelCase name}}.
{{/zcl_events}}
} // namespace Events

} // namespace {{asUpperCamelCase name}}
{{/zcl_clusters}}

} // namespace Clusters

bool CommandNeedsTimedInvoke(ClusterId aCluster, CommandId aCommand)
{
    // Maybe it would be smaller code to codegen a table and walk over it?
    // Not sure.
    switch (aCluster)
    {
    {{#zcl_clusters}}
      {{#zcl_commands_that_need_timed_invoke}}
      {{#first}}
      case Clusters::{{asUpperCamelCase parent.name}}::Id:
      {
          switch (aCommand) {
      {{/first}}
          case Clusters::{{asUpperCamelCase parent.name}}::Commands::{{asUpperCamelCase name}}::Id:
      {{#last}}
              return true;
          default:
              return false;
          }
      }
      {{/last}}
      {{/zcl_commands_that_need_timed_invoke}}
    {{/zcl_clusters}}
    default:
        break;
    }

    return false;
}

bool CommandIsFabricScoped(ClusterId aCluster, CommandId aCommand)
{
    // Maybe it would be smaller code to codegen a table and walk over it?
    // Not sure.
    switch (aCluster)
    {
    {{#zcl_clusters}}
      {{#zcl_commands}}
      {{#first}}
      case Clusters::{{asUpperCamelCase parent.name}}::Id:
      {
          switch (aCommand) {
      {{/first}}
          {{#if isFabricScoped}}
          case Clusters::{{asUpperCamelCase parent.name}}::Commands::{{asUpperCamelCase name}}::Id:
              return true;
          {{/if}}
      {{#last}}
          default:
              return false;
          }
      }
      {{/last}}
      {{/zcl_commands}}
    {{/zcl_clusters}}
    }
    return false;
}

} // namespace app
} // namespace chip
