/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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
 *
 *   https://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.
 */

package model

import (
	"context"
	stdErrors "errors"
	"fmt"

	"github.com/pkg/errors"
	"github.com/rs/zerolog"

	. "github.com/apache/plc4x/plc4go/spi/codegen/fields"
	. "github.com/apache/plc4x/plc4go/spi/codegen/io"
	"github.com/apache/plc4x/plc4go/spi/utils"
)

// Code generated by code-generation. DO NOT EDIT.

// BACnetPriorityArray is the corresponding interface of BACnetPriorityArray
type BACnetPriorityArray interface {
	fmt.Stringer
	utils.LengthAware
	utils.Serializable
	utils.Copyable
	// GetNumberOfDataElements returns NumberOfDataElements (property field)
	GetNumberOfDataElements() BACnetApplicationTagUnsignedInteger
	// GetData returns Data (property field)
	GetData() []BACnetPriorityValue
	// GetZero returns Zero (virtual field)
	// TODO: uint 64 ---> big int in java == boom
	GetZero() uint64
	// GetPriorityValue01 returns PriorityValue01 (virtual field)
	GetPriorityValue01() BACnetPriorityValue
	// GetPriorityValue02 returns PriorityValue02 (virtual field)
	GetPriorityValue02() BACnetPriorityValue
	// GetPriorityValue03 returns PriorityValue03 (virtual field)
	GetPriorityValue03() BACnetPriorityValue
	// GetPriorityValue04 returns PriorityValue04 (virtual field)
	GetPriorityValue04() BACnetPriorityValue
	// GetPriorityValue05 returns PriorityValue05 (virtual field)
	GetPriorityValue05() BACnetPriorityValue
	// GetPriorityValue06 returns PriorityValue06 (virtual field)
	GetPriorityValue06() BACnetPriorityValue
	// GetPriorityValue07 returns PriorityValue07 (virtual field)
	GetPriorityValue07() BACnetPriorityValue
	// GetPriorityValue08 returns PriorityValue08 (virtual field)
	GetPriorityValue08() BACnetPriorityValue
	// GetPriorityValue09 returns PriorityValue09 (virtual field)
	GetPriorityValue09() BACnetPriorityValue
	// GetPriorityValue10 returns PriorityValue10 (virtual field)
	GetPriorityValue10() BACnetPriorityValue
	// GetPriorityValue11 returns PriorityValue11 (virtual field)
	GetPriorityValue11() BACnetPriorityValue
	// GetPriorityValue12 returns PriorityValue12 (virtual field)
	GetPriorityValue12() BACnetPriorityValue
	// GetPriorityValue13 returns PriorityValue13 (virtual field)
	GetPriorityValue13() BACnetPriorityValue
	// GetPriorityValue14 returns PriorityValue14 (virtual field)
	GetPriorityValue14() BACnetPriorityValue
	// GetPriorityValue15 returns PriorityValue15 (virtual field)
	GetPriorityValue15() BACnetPriorityValue
	// GetPriorityValue16 returns PriorityValue16 (virtual field)
	GetPriorityValue16() BACnetPriorityValue
	// GetIsIndexedAccess returns IsIndexedAccess (virtual field)
	GetIsIndexedAccess() bool
	// GetIndexEntry returns IndexEntry (virtual field)
	GetIndexEntry() BACnetPriorityValue
	// IsBACnetPriorityArray is a marker method to prevent unintentional type checks (interfaces of same signature)
	IsBACnetPriorityArray()
	// CreateBuilder creates a BACnetPriorityArrayBuilder
	CreateBACnetPriorityArrayBuilder() BACnetPriorityArrayBuilder
}

// _BACnetPriorityArray is the data-structure of this message
type _BACnetPriorityArray struct {
	NumberOfDataElements BACnetApplicationTagUnsignedInteger
	Data                 []BACnetPriorityValue
}

var _ BACnetPriorityArray = (*_BACnetPriorityArray)(nil)

// NewBACnetPriorityArray factory function for _BACnetPriorityArray
func NewBACnetPriorityArray(numberOfDataElements BACnetApplicationTagUnsignedInteger, data []BACnetPriorityValue) *_BACnetPriorityArray {
	return &_BACnetPriorityArray{NumberOfDataElements: numberOfDataElements, Data: data}
}

///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
/////////////////////// Builder
///////////////////////

// BACnetPriorityArrayBuilder is a builder for BACnetPriorityArray
type BACnetPriorityArrayBuilder interface {
	utils.Copyable
	// WithMandatoryFields adds all mandatory fields (convenience for using multiple builder calls)
	WithMandatoryFields(data []BACnetPriorityValue) BACnetPriorityArrayBuilder
	// WithNumberOfDataElements adds NumberOfDataElements (property field)
	WithOptionalNumberOfDataElements(BACnetApplicationTagUnsignedInteger) BACnetPriorityArrayBuilder
	// WithOptionalNumberOfDataElementsBuilder adds NumberOfDataElements (property field) which is build by the builder
	WithOptionalNumberOfDataElementsBuilder(func(BACnetApplicationTagUnsignedIntegerBuilder) BACnetApplicationTagUnsignedIntegerBuilder) BACnetPriorityArrayBuilder
	// WithData adds Data (property field)
	WithData(...BACnetPriorityValue) BACnetPriorityArrayBuilder
	// Build builds the BACnetPriorityArray or returns an error if something is wrong
	Build() (BACnetPriorityArray, error)
	// MustBuild does the same as Build but panics on error
	MustBuild() BACnetPriorityArray
}

// NewBACnetPriorityArrayBuilder() creates a BACnetPriorityArrayBuilder
func NewBACnetPriorityArrayBuilder() BACnetPriorityArrayBuilder {
	return &_BACnetPriorityArrayBuilder{_BACnetPriorityArray: new(_BACnetPriorityArray)}
}

type _BACnetPriorityArrayBuilder struct {
	*_BACnetPriorityArray

	collectedErr []error
}

var _ (BACnetPriorityArrayBuilder) = (*_BACnetPriorityArrayBuilder)(nil)

func (b *_BACnetPriorityArrayBuilder) WithMandatoryFields(data []BACnetPriorityValue) BACnetPriorityArrayBuilder {
	return b.WithData(data...)
}

func (b *_BACnetPriorityArrayBuilder) WithOptionalNumberOfDataElements(numberOfDataElements BACnetApplicationTagUnsignedInteger) BACnetPriorityArrayBuilder {
	b.NumberOfDataElements = numberOfDataElements
	return b
}

func (b *_BACnetPriorityArrayBuilder) WithOptionalNumberOfDataElementsBuilder(builderSupplier func(BACnetApplicationTagUnsignedIntegerBuilder) BACnetApplicationTagUnsignedIntegerBuilder) BACnetPriorityArrayBuilder {
	builder := builderSupplier(b.NumberOfDataElements.CreateBACnetApplicationTagUnsignedIntegerBuilder())
	var err error
	b.NumberOfDataElements, err = builder.Build()
	if err != nil {
		b.collectedErr = append(b.collectedErr, errors.Wrap(err, "BACnetApplicationTagUnsignedIntegerBuilder failed"))
	}
	return b
}

func (b *_BACnetPriorityArrayBuilder) WithData(data ...BACnetPriorityValue) BACnetPriorityArrayBuilder {
	b.Data = data
	return b
}

func (b *_BACnetPriorityArrayBuilder) Build() (BACnetPriorityArray, error) {
	if err := stdErrors.Join(b.collectedErr...); err != nil {
		return nil, errors.Wrap(err, "error occurred during build")
	}
	return b._BACnetPriorityArray.deepCopy(), nil
}

func (b *_BACnetPriorityArrayBuilder) MustBuild() BACnetPriorityArray {
	build, err := b.Build()
	if err != nil {
		panic(err)
	}
	return build
}

func (b *_BACnetPriorityArrayBuilder) DeepCopy() any {
	_copy := b.CreateBACnetPriorityArrayBuilder().(*_BACnetPriorityArrayBuilder)
	if b.collectedErr != nil {
		copy(_copy.collectedErr, b.collectedErr)
	}
	return _copy
}

// CreateBACnetPriorityArrayBuilder creates a BACnetPriorityArrayBuilder
func (b *_BACnetPriorityArray) CreateBACnetPriorityArrayBuilder() BACnetPriorityArrayBuilder {
	if b == nil {
		return NewBACnetPriorityArrayBuilder()
	}
	return &_BACnetPriorityArrayBuilder{_BACnetPriorityArray: b.deepCopy()}
}

///////////////////////
///////////////////////
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
/////////////////////// Accessors for property fields.
///////////////////////

func (m *_BACnetPriorityArray) GetNumberOfDataElements() BACnetApplicationTagUnsignedInteger {
	return m.NumberOfDataElements
}

func (m *_BACnetPriorityArray) GetData() []BACnetPriorityValue {
	return m.Data
}

///////////////////////
///////////////////////
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
/////////////////////// Accessors for virtual fields.
///////////////////////

func (m *_BACnetPriorityArray) GetZero() uint64 {
	ctx := context.Background()
	_ = ctx
	numberOfDataElements := m.GetNumberOfDataElements()
	_ = numberOfDataElements
	return uint64(uint64(0))
}

func (m *_BACnetPriorityArray) GetPriorityValue01() BACnetPriorityValue {
	ctx := context.Background()
	_ = ctx
	numberOfDataElements := m.GetNumberOfDataElements()
	_ = numberOfDataElements
	return CastBACnetPriorityValue(CastBACnetPriorityValue(utils.InlineIf(bool((len(m.GetData())) > (0)), func() any { return CastBACnetPriorityValue(m.GetData()[0]) }, func() any { return CastBACnetPriorityValue(nil) })))
}

func (m *_BACnetPriorityArray) GetPriorityValue02() BACnetPriorityValue {
	ctx := context.Background()
	_ = ctx
	numberOfDataElements := m.GetNumberOfDataElements()
	_ = numberOfDataElements
	return CastBACnetPriorityValue(CastBACnetPriorityValue(utils.InlineIf(bool((len(m.GetData())) > (1)), func() any { return CastBACnetPriorityValue(m.GetData()[1]) }, func() any { return CastBACnetPriorityValue(nil) })))
}

func (m *_BACnetPriorityArray) GetPriorityValue03() BACnetPriorityValue {
	ctx := context.Background()
	_ = ctx
	numberOfDataElements := m.GetNumberOfDataElements()
	_ = numberOfDataElements
	return CastBACnetPriorityValue(CastBACnetPriorityValue(utils.InlineIf(bool((len(m.GetData())) > (2)), func() any { return CastBACnetPriorityValue(m.GetData()[2]) }, func() any { return CastBACnetPriorityValue(nil) })))
}

func (m *_BACnetPriorityArray) GetPriorityValue04() BACnetPriorityValue {
	ctx := context.Background()
	_ = ctx
	numberOfDataElements := m.GetNumberOfDataElements()
	_ = numberOfDataElements
	return CastBACnetPriorityValue(CastBACnetPriorityValue(utils.InlineIf(bool((len(m.GetData())) > (3)), func() any { return CastBACnetPriorityValue(m.GetData()[3]) }, func() any { return CastBACnetPriorityValue(nil) })))
}

func (m *_BACnetPriorityArray) GetPriorityValue05() BACnetPriorityValue {
	ctx := context.Background()
	_ = ctx
	numberOfDataElements := m.GetNumberOfDataElements()
	_ = numberOfDataElements
	return CastBACnetPriorityValue(CastBACnetPriorityValue(utils.InlineIf(bool((len(m.GetData())) > (4)), func() any { return CastBACnetPriorityValue(m.GetData()[4]) }, func() any { return CastBACnetPriorityValue(nil) })))
}

func (m *_BACnetPriorityArray) GetPriorityValue06() BACnetPriorityValue {
	ctx := context.Background()
	_ = ctx
	numberOfDataElements := m.GetNumberOfDataElements()
	_ = numberOfDataElements
	return CastBACnetPriorityValue(CastBACnetPriorityValue(utils.InlineIf(bool((len(m.GetData())) > (5)), func() any { return CastBACnetPriorityValue(m.GetData()[5]) }, func() any { return CastBACnetPriorityValue(nil) })))
}

func (m *_BACnetPriorityArray) GetPriorityValue07() BACnetPriorityValue {
	ctx := context.Background()
	_ = ctx
	numberOfDataElements := m.GetNumberOfDataElements()
	_ = numberOfDataElements
	return CastBACnetPriorityValue(CastBACnetPriorityValue(utils.InlineIf(bool((len(m.GetData())) > (6)), func() any { return CastBACnetPriorityValue(m.GetData()[6]) }, func() any { return CastBACnetPriorityValue(nil) })))
}

func (m *_BACnetPriorityArray) GetPriorityValue08() BACnetPriorityValue {
	ctx := context.Background()
	_ = ctx
	numberOfDataElements := m.GetNumberOfDataElements()
	_ = numberOfDataElements
	return CastBACnetPriorityValue(CastBACnetPriorityValue(utils.InlineIf(bool((len(m.GetData())) > (7)), func() any { return CastBACnetPriorityValue(m.GetData()[7]) }, func() any { return CastBACnetPriorityValue(nil) })))
}

func (m *_BACnetPriorityArray) GetPriorityValue09() BACnetPriorityValue {
	ctx := context.Background()
	_ = ctx
	numberOfDataElements := m.GetNumberOfDataElements()
	_ = numberOfDataElements
	return CastBACnetPriorityValue(CastBACnetPriorityValue(utils.InlineIf(bool((len(m.GetData())) > (8)), func() any { return CastBACnetPriorityValue(m.GetData()[8]) }, func() any { return CastBACnetPriorityValue(nil) })))
}

func (m *_BACnetPriorityArray) GetPriorityValue10() BACnetPriorityValue {
	ctx := context.Background()
	_ = ctx
	numberOfDataElements := m.GetNumberOfDataElements()
	_ = numberOfDataElements
	return CastBACnetPriorityValue(CastBACnetPriorityValue(utils.InlineIf(bool((len(m.GetData())) > (9)), func() any { return CastBACnetPriorityValue(m.GetData()[9]) }, func() any { return CastBACnetPriorityValue(nil) })))
}

func (m *_BACnetPriorityArray) GetPriorityValue11() BACnetPriorityValue {
	ctx := context.Background()
	_ = ctx
	numberOfDataElements := m.GetNumberOfDataElements()
	_ = numberOfDataElements
	return CastBACnetPriorityValue(CastBACnetPriorityValue(utils.InlineIf(bool((len(m.GetData())) > (10)), func() any { return CastBACnetPriorityValue(m.GetData()[10]) }, func() any { return CastBACnetPriorityValue(nil) })))
}

func (m *_BACnetPriorityArray) GetPriorityValue12() BACnetPriorityValue {
	ctx := context.Background()
	_ = ctx
	numberOfDataElements := m.GetNumberOfDataElements()
	_ = numberOfDataElements
	return CastBACnetPriorityValue(CastBACnetPriorityValue(utils.InlineIf(bool((len(m.GetData())) > (11)), func() any { return CastBACnetPriorityValue(m.GetData()[11]) }, func() any { return CastBACnetPriorityValue(nil) })))
}

func (m *_BACnetPriorityArray) GetPriorityValue13() BACnetPriorityValue {
	ctx := context.Background()
	_ = ctx
	numberOfDataElements := m.GetNumberOfDataElements()
	_ = numberOfDataElements
	return CastBACnetPriorityValue(CastBACnetPriorityValue(utils.InlineIf(bool((len(m.GetData())) > (12)), func() any { return CastBACnetPriorityValue(m.GetData()[12]) }, func() any { return CastBACnetPriorityValue(nil) })))
}

func (m *_BACnetPriorityArray) GetPriorityValue14() BACnetPriorityValue {
	ctx := context.Background()
	_ = ctx
	numberOfDataElements := m.GetNumberOfDataElements()
	_ = numberOfDataElements
	return CastBACnetPriorityValue(CastBACnetPriorityValue(utils.InlineIf(bool((len(m.GetData())) > (13)), func() any { return CastBACnetPriorityValue(m.GetData()[13]) }, func() any { return CastBACnetPriorityValue(nil) })))
}

func (m *_BACnetPriorityArray) GetPriorityValue15() BACnetPriorityValue {
	ctx := context.Background()
	_ = ctx
	numberOfDataElements := m.GetNumberOfDataElements()
	_ = numberOfDataElements
	return CastBACnetPriorityValue(CastBACnetPriorityValue(utils.InlineIf(bool((len(m.GetData())) > (14)), func() any { return CastBACnetPriorityValue(m.GetData()[14]) }, func() any { return CastBACnetPriorityValue(nil) })))
}

func (m *_BACnetPriorityArray) GetPriorityValue16() BACnetPriorityValue {
	ctx := context.Background()
	_ = ctx
	numberOfDataElements := m.GetNumberOfDataElements()
	_ = numberOfDataElements
	return CastBACnetPriorityValue(CastBACnetPriorityValue(utils.InlineIf(bool((len(m.GetData())) > (15)), func() any { return CastBACnetPriorityValue(m.GetData()[15]) }, func() any { return CastBACnetPriorityValue(nil) })))
}

func (m *_BACnetPriorityArray) GetIsIndexedAccess() bool {
	ctx := context.Background()
	_ = ctx
	numberOfDataElements := m.GetNumberOfDataElements()
	_ = numberOfDataElements
	return bool(bool((len(m.GetData())) == (1)))
}

func (m *_BACnetPriorityArray) GetIndexEntry() BACnetPriorityValue {
	ctx := context.Background()
	_ = ctx
	numberOfDataElements := m.GetNumberOfDataElements()
	_ = numberOfDataElements
	return CastBACnetPriorityValue(m.GetPriorityValue01())
}

///////////////////////
///////////////////////
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////

// Deprecated: use the interface for direct cast
func CastBACnetPriorityArray(structType any) BACnetPriorityArray {
	if casted, ok := structType.(BACnetPriorityArray); ok {
		return casted
	}
	if casted, ok := structType.(*BACnetPriorityArray); ok {
		return *casted
	}
	return nil
}

func (m *_BACnetPriorityArray) GetTypeName() string {
	return "BACnetPriorityArray"
}

func (m *_BACnetPriorityArray) GetLengthInBits(ctx context.Context) uint16 {
	lengthInBits := uint16(0)

	// A virtual field doesn't have any in- or output.

	// Optional Field (numberOfDataElements)
	if m.NumberOfDataElements != nil {
		lengthInBits += m.NumberOfDataElements.GetLengthInBits(ctx)
	}

	// Array field
	if len(m.Data) > 0 {
		for _, element := range m.Data {
			lengthInBits += element.GetLengthInBits(ctx)
		}
	}

	// A virtual field doesn't have any in- or output.

	// A virtual field doesn't have any in- or output.

	// A virtual field doesn't have any in- or output.

	// A virtual field doesn't have any in- or output.

	// A virtual field doesn't have any in- or output.

	// A virtual field doesn't have any in- or output.

	// A virtual field doesn't have any in- or output.

	// A virtual field doesn't have any in- or output.

	// A virtual field doesn't have any in- or output.

	// A virtual field doesn't have any in- or output.

	// A virtual field doesn't have any in- or output.

	// A virtual field doesn't have any in- or output.

	// A virtual field doesn't have any in- or output.

	// A virtual field doesn't have any in- or output.

	// A virtual field doesn't have any in- or output.

	// A virtual field doesn't have any in- or output.

	// A virtual field doesn't have any in- or output.

	// A virtual field doesn't have any in- or output.

	return lengthInBits
}

func (m *_BACnetPriorityArray) GetLengthInBytes(ctx context.Context) uint16 {
	return m.GetLengthInBits(ctx) / 8
}

func BACnetPriorityArrayParse(ctx context.Context, theBytes []byte, objectTypeArgument BACnetObjectType, tagNumber uint8, arrayIndexArgument BACnetTagPayloadUnsignedInteger) (BACnetPriorityArray, error) {
	return BACnetPriorityArrayParseWithBuffer(ctx, utils.NewReadBufferByteBased(theBytes), objectTypeArgument, tagNumber, arrayIndexArgument)
}

func BACnetPriorityArrayParseWithBufferProducer(objectTypeArgument BACnetObjectType, tagNumber uint8, arrayIndexArgument BACnetTagPayloadUnsignedInteger) func(ctx context.Context, readBuffer utils.ReadBuffer) (BACnetPriorityArray, error) {
	return func(ctx context.Context, readBuffer utils.ReadBuffer) (BACnetPriorityArray, error) {
		return BACnetPriorityArrayParseWithBuffer(ctx, readBuffer, objectTypeArgument, tagNumber, arrayIndexArgument)
	}
}

func BACnetPriorityArrayParseWithBuffer(ctx context.Context, readBuffer utils.ReadBuffer, objectTypeArgument BACnetObjectType, tagNumber uint8, arrayIndexArgument BACnetTagPayloadUnsignedInteger) (BACnetPriorityArray, error) {
	v, err := (new(_BACnetPriorityArray)).parse(ctx, readBuffer, objectTypeArgument, tagNumber, arrayIndexArgument)
	if err != nil {
		return nil, err
	}
	return v, nil
}

func (m *_BACnetPriorityArray) parse(ctx context.Context, readBuffer utils.ReadBuffer, objectTypeArgument BACnetObjectType, tagNumber uint8, arrayIndexArgument BACnetTagPayloadUnsignedInteger) (__bACnetPriorityArray BACnetPriorityArray, err error) {
	positionAware := readBuffer
	_ = positionAware
	if pullErr := readBuffer.PullContext("BACnetPriorityArray"); pullErr != nil {
		return nil, errors.Wrap(pullErr, "Error pulling for BACnetPriorityArray")
	}
	currentPos := positionAware.GetPos()
	_ = currentPos

	zero, err := ReadVirtualField[uint64](ctx, "zero", (*uint64)(nil), uint64(0))
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'zero' field"))
	}
	_ = zero

	var numberOfDataElements BACnetApplicationTagUnsignedInteger
	_numberOfDataElements, err := ReadOptionalField[BACnetApplicationTagUnsignedInteger](ctx, "numberOfDataElements", ReadComplex[BACnetApplicationTagUnsignedInteger](BACnetApplicationTagParseWithBufferProducer[BACnetApplicationTagUnsignedInteger](), readBuffer), bool(bool((arrayIndexArgument) != (nil))) && bool(bool((arrayIndexArgument.GetActualValue()) == (zero))))
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'numberOfDataElements' field"))
	}
	if _numberOfDataElements != nil {
		numberOfDataElements = *_numberOfDataElements
		m.NumberOfDataElements = numberOfDataElements
	}

	data, err := ReadTerminatedArrayField[BACnetPriorityValue](ctx, "data", ReadComplex[BACnetPriorityValue](BACnetPriorityValueParseWithBufferProducer[BACnetPriorityValue]((BACnetObjectType)(objectTypeArgument)), readBuffer), IsBACnetConstructedDataClosingTag(ctx, readBuffer, false, tagNumber))
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'data' field"))
	}
	m.Data = data

	priorityValue01, err := ReadVirtualField[BACnetPriorityValue](ctx, "priorityValue01", (*BACnetPriorityValue)(nil), CastBACnetPriorityValue(utils.InlineIf(bool((len(data)) > (0)), func() any { return CastBACnetPriorityValue(data[0]) }, func() any { return CastBACnetPriorityValue(nil) })))
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'priorityValue01' field"))
	}
	_ = priorityValue01

	priorityValue02, err := ReadVirtualField[BACnetPriorityValue](ctx, "priorityValue02", (*BACnetPriorityValue)(nil), CastBACnetPriorityValue(utils.InlineIf(bool((len(data)) > (1)), func() any { return CastBACnetPriorityValue(data[1]) }, func() any { return CastBACnetPriorityValue(nil) })))
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'priorityValue02' field"))
	}
	_ = priorityValue02

	priorityValue03, err := ReadVirtualField[BACnetPriorityValue](ctx, "priorityValue03", (*BACnetPriorityValue)(nil), CastBACnetPriorityValue(utils.InlineIf(bool((len(data)) > (2)), func() any { return CastBACnetPriorityValue(data[2]) }, func() any { return CastBACnetPriorityValue(nil) })))
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'priorityValue03' field"))
	}
	_ = priorityValue03

	priorityValue04, err := ReadVirtualField[BACnetPriorityValue](ctx, "priorityValue04", (*BACnetPriorityValue)(nil), CastBACnetPriorityValue(utils.InlineIf(bool((len(data)) > (3)), func() any { return CastBACnetPriorityValue(data[3]) }, func() any { return CastBACnetPriorityValue(nil) })))
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'priorityValue04' field"))
	}
	_ = priorityValue04

	priorityValue05, err := ReadVirtualField[BACnetPriorityValue](ctx, "priorityValue05", (*BACnetPriorityValue)(nil), CastBACnetPriorityValue(utils.InlineIf(bool((len(data)) > (4)), func() any { return CastBACnetPriorityValue(data[4]) }, func() any { return CastBACnetPriorityValue(nil) })))
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'priorityValue05' field"))
	}
	_ = priorityValue05

	priorityValue06, err := ReadVirtualField[BACnetPriorityValue](ctx, "priorityValue06", (*BACnetPriorityValue)(nil), CastBACnetPriorityValue(utils.InlineIf(bool((len(data)) > (5)), func() any { return CastBACnetPriorityValue(data[5]) }, func() any { return CastBACnetPriorityValue(nil) })))
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'priorityValue06' field"))
	}
	_ = priorityValue06

	priorityValue07, err := ReadVirtualField[BACnetPriorityValue](ctx, "priorityValue07", (*BACnetPriorityValue)(nil), CastBACnetPriorityValue(utils.InlineIf(bool((len(data)) > (6)), func() any { return CastBACnetPriorityValue(data[6]) }, func() any { return CastBACnetPriorityValue(nil) })))
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'priorityValue07' field"))
	}
	_ = priorityValue07

	priorityValue08, err := ReadVirtualField[BACnetPriorityValue](ctx, "priorityValue08", (*BACnetPriorityValue)(nil), CastBACnetPriorityValue(utils.InlineIf(bool((len(data)) > (7)), func() any { return CastBACnetPriorityValue(data[7]) }, func() any { return CastBACnetPriorityValue(nil) })))
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'priorityValue08' field"))
	}
	_ = priorityValue08

	priorityValue09, err := ReadVirtualField[BACnetPriorityValue](ctx, "priorityValue09", (*BACnetPriorityValue)(nil), CastBACnetPriorityValue(utils.InlineIf(bool((len(data)) > (8)), func() any { return CastBACnetPriorityValue(data[8]) }, func() any { return CastBACnetPriorityValue(nil) })))
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'priorityValue09' field"))
	}
	_ = priorityValue09

	priorityValue10, err := ReadVirtualField[BACnetPriorityValue](ctx, "priorityValue10", (*BACnetPriorityValue)(nil), CastBACnetPriorityValue(utils.InlineIf(bool((len(data)) > (9)), func() any { return CastBACnetPriorityValue(data[9]) }, func() any { return CastBACnetPriorityValue(nil) })))
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'priorityValue10' field"))
	}
	_ = priorityValue10

	priorityValue11, err := ReadVirtualField[BACnetPriorityValue](ctx, "priorityValue11", (*BACnetPriorityValue)(nil), CastBACnetPriorityValue(utils.InlineIf(bool((len(data)) > (10)), func() any { return CastBACnetPriorityValue(data[10]) }, func() any { return CastBACnetPriorityValue(nil) })))
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'priorityValue11' field"))
	}
	_ = priorityValue11

	priorityValue12, err := ReadVirtualField[BACnetPriorityValue](ctx, "priorityValue12", (*BACnetPriorityValue)(nil), CastBACnetPriorityValue(utils.InlineIf(bool((len(data)) > (11)), func() any { return CastBACnetPriorityValue(data[11]) }, func() any { return CastBACnetPriorityValue(nil) })))
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'priorityValue12' field"))
	}
	_ = priorityValue12

	priorityValue13, err := ReadVirtualField[BACnetPriorityValue](ctx, "priorityValue13", (*BACnetPriorityValue)(nil), CastBACnetPriorityValue(utils.InlineIf(bool((len(data)) > (12)), func() any { return CastBACnetPriorityValue(data[12]) }, func() any { return CastBACnetPriorityValue(nil) })))
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'priorityValue13' field"))
	}
	_ = priorityValue13

	priorityValue14, err := ReadVirtualField[BACnetPriorityValue](ctx, "priorityValue14", (*BACnetPriorityValue)(nil), CastBACnetPriorityValue(utils.InlineIf(bool((len(data)) > (13)), func() any { return CastBACnetPriorityValue(data[13]) }, func() any { return CastBACnetPriorityValue(nil) })))
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'priorityValue14' field"))
	}
	_ = priorityValue14

	priorityValue15, err := ReadVirtualField[BACnetPriorityValue](ctx, "priorityValue15", (*BACnetPriorityValue)(nil), CastBACnetPriorityValue(utils.InlineIf(bool((len(data)) > (14)), func() any { return CastBACnetPriorityValue(data[14]) }, func() any { return CastBACnetPriorityValue(nil) })))
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'priorityValue15' field"))
	}
	_ = priorityValue15

	priorityValue16, err := ReadVirtualField[BACnetPriorityValue](ctx, "priorityValue16", (*BACnetPriorityValue)(nil), CastBACnetPriorityValue(utils.InlineIf(bool((len(data)) > (15)), func() any { return CastBACnetPriorityValue(data[15]) }, func() any { return CastBACnetPriorityValue(nil) })))
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'priorityValue16' field"))
	}
	_ = priorityValue16

	// Validation
	if !(bool(bool((arrayIndexArgument) != (nil))) || bool(bool((len(data)) == (16)))) {
		return nil, errors.WithStack(utils.ParseValidationError{Message: "Either indexed access or lenght 16 expected"})
	}

	isIndexedAccess, err := ReadVirtualField[bool](ctx, "isIndexedAccess", (*bool)(nil), bool((len(data)) == (1)))
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'isIndexedAccess' field"))
	}
	_ = isIndexedAccess

	indexEntry, err := ReadVirtualField[BACnetPriorityValue](ctx, "indexEntry", (*BACnetPriorityValue)(nil), priorityValue01)
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'indexEntry' field"))
	}
	_ = indexEntry

	if closeErr := readBuffer.CloseContext("BACnetPriorityArray"); closeErr != nil {
		return nil, errors.Wrap(closeErr, "Error closing for BACnetPriorityArray")
	}

	return m, nil
}

func (m *_BACnetPriorityArray) Serialize() ([]byte, error) {
	wb := utils.NewWriteBufferByteBased(utils.WithInitialSizeForByteBasedBuffer(int(m.GetLengthInBytes(context.Background()))))
	if err := m.SerializeWithWriteBuffer(context.Background(), wb); err != nil {
		return nil, err
	}
	return wb.GetBytes(), nil
}

func (m *_BACnetPriorityArray) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
	positionAware := writeBuffer
	_ = positionAware
	log := zerolog.Ctx(ctx)
	_ = log
	if pushErr := writeBuffer.PushContext("BACnetPriorityArray"); pushErr != nil {
		return errors.Wrap(pushErr, "Error pushing for BACnetPriorityArray")
	}
	// Virtual field
	zero := m.GetZero()
	_ = zero
	if _zeroErr := writeBuffer.WriteVirtual(ctx, "zero", m.GetZero()); _zeroErr != nil {
		return errors.Wrap(_zeroErr, "Error serializing 'zero' field")
	}

	if err := WriteOptionalField[BACnetApplicationTagUnsignedInteger](ctx, "numberOfDataElements", GetRef(m.GetNumberOfDataElements()), WriteComplex[BACnetApplicationTagUnsignedInteger](writeBuffer), true); err != nil {
		return errors.Wrap(err, "Error serializing 'numberOfDataElements' field")
	}

	if err := WriteComplexTypeArrayField(ctx, "data", m.GetData(), writeBuffer); err != nil {
		return errors.Wrap(err, "Error serializing 'data' field")
	}
	// Virtual field
	priorityValue01 := m.GetPriorityValue01()
	_ = priorityValue01
	if _priorityValue01Err := writeBuffer.WriteVirtual(ctx, "priorityValue01", m.GetPriorityValue01()); _priorityValue01Err != nil {
		return errors.Wrap(_priorityValue01Err, "Error serializing 'priorityValue01' field")
	}
	// Virtual field
	priorityValue02 := m.GetPriorityValue02()
	_ = priorityValue02
	if _priorityValue02Err := writeBuffer.WriteVirtual(ctx, "priorityValue02", m.GetPriorityValue02()); _priorityValue02Err != nil {
		return errors.Wrap(_priorityValue02Err, "Error serializing 'priorityValue02' field")
	}
	// Virtual field
	priorityValue03 := m.GetPriorityValue03()
	_ = priorityValue03
	if _priorityValue03Err := writeBuffer.WriteVirtual(ctx, "priorityValue03", m.GetPriorityValue03()); _priorityValue03Err != nil {
		return errors.Wrap(_priorityValue03Err, "Error serializing 'priorityValue03' field")
	}
	// Virtual field
	priorityValue04 := m.GetPriorityValue04()
	_ = priorityValue04
	if _priorityValue04Err := writeBuffer.WriteVirtual(ctx, "priorityValue04", m.GetPriorityValue04()); _priorityValue04Err != nil {
		return errors.Wrap(_priorityValue04Err, "Error serializing 'priorityValue04' field")
	}
	// Virtual field
	priorityValue05 := m.GetPriorityValue05()
	_ = priorityValue05
	if _priorityValue05Err := writeBuffer.WriteVirtual(ctx, "priorityValue05", m.GetPriorityValue05()); _priorityValue05Err != nil {
		return errors.Wrap(_priorityValue05Err, "Error serializing 'priorityValue05' field")
	}
	// Virtual field
	priorityValue06 := m.GetPriorityValue06()
	_ = priorityValue06
	if _priorityValue06Err := writeBuffer.WriteVirtual(ctx, "priorityValue06", m.GetPriorityValue06()); _priorityValue06Err != nil {
		return errors.Wrap(_priorityValue06Err, "Error serializing 'priorityValue06' field")
	}
	// Virtual field
	priorityValue07 := m.GetPriorityValue07()
	_ = priorityValue07
	if _priorityValue07Err := writeBuffer.WriteVirtual(ctx, "priorityValue07", m.GetPriorityValue07()); _priorityValue07Err != nil {
		return errors.Wrap(_priorityValue07Err, "Error serializing 'priorityValue07' field")
	}
	// Virtual field
	priorityValue08 := m.GetPriorityValue08()
	_ = priorityValue08
	if _priorityValue08Err := writeBuffer.WriteVirtual(ctx, "priorityValue08", m.GetPriorityValue08()); _priorityValue08Err != nil {
		return errors.Wrap(_priorityValue08Err, "Error serializing 'priorityValue08' field")
	}
	// Virtual field
	priorityValue09 := m.GetPriorityValue09()
	_ = priorityValue09
	if _priorityValue09Err := writeBuffer.WriteVirtual(ctx, "priorityValue09", m.GetPriorityValue09()); _priorityValue09Err != nil {
		return errors.Wrap(_priorityValue09Err, "Error serializing 'priorityValue09' field")
	}
	// Virtual field
	priorityValue10 := m.GetPriorityValue10()
	_ = priorityValue10
	if _priorityValue10Err := writeBuffer.WriteVirtual(ctx, "priorityValue10", m.GetPriorityValue10()); _priorityValue10Err != nil {
		return errors.Wrap(_priorityValue10Err, "Error serializing 'priorityValue10' field")
	}
	// Virtual field
	priorityValue11 := m.GetPriorityValue11()
	_ = priorityValue11
	if _priorityValue11Err := writeBuffer.WriteVirtual(ctx, "priorityValue11", m.GetPriorityValue11()); _priorityValue11Err != nil {
		return errors.Wrap(_priorityValue11Err, "Error serializing 'priorityValue11' field")
	}
	// Virtual field
	priorityValue12 := m.GetPriorityValue12()
	_ = priorityValue12
	if _priorityValue12Err := writeBuffer.WriteVirtual(ctx, "priorityValue12", m.GetPriorityValue12()); _priorityValue12Err != nil {
		return errors.Wrap(_priorityValue12Err, "Error serializing 'priorityValue12' field")
	}
	// Virtual field
	priorityValue13 := m.GetPriorityValue13()
	_ = priorityValue13
	if _priorityValue13Err := writeBuffer.WriteVirtual(ctx, "priorityValue13", m.GetPriorityValue13()); _priorityValue13Err != nil {
		return errors.Wrap(_priorityValue13Err, "Error serializing 'priorityValue13' field")
	}
	// Virtual field
	priorityValue14 := m.GetPriorityValue14()
	_ = priorityValue14
	if _priorityValue14Err := writeBuffer.WriteVirtual(ctx, "priorityValue14", m.GetPriorityValue14()); _priorityValue14Err != nil {
		return errors.Wrap(_priorityValue14Err, "Error serializing 'priorityValue14' field")
	}
	// Virtual field
	priorityValue15 := m.GetPriorityValue15()
	_ = priorityValue15
	if _priorityValue15Err := writeBuffer.WriteVirtual(ctx, "priorityValue15", m.GetPriorityValue15()); _priorityValue15Err != nil {
		return errors.Wrap(_priorityValue15Err, "Error serializing 'priorityValue15' field")
	}
	// Virtual field
	priorityValue16 := m.GetPriorityValue16()
	_ = priorityValue16
	if _priorityValue16Err := writeBuffer.WriteVirtual(ctx, "priorityValue16", m.GetPriorityValue16()); _priorityValue16Err != nil {
		return errors.Wrap(_priorityValue16Err, "Error serializing 'priorityValue16' field")
	}
	// Virtual field
	isIndexedAccess := m.GetIsIndexedAccess()
	_ = isIndexedAccess
	if _isIndexedAccessErr := writeBuffer.WriteVirtual(ctx, "isIndexedAccess", m.GetIsIndexedAccess()); _isIndexedAccessErr != nil {
		return errors.Wrap(_isIndexedAccessErr, "Error serializing 'isIndexedAccess' field")
	}
	// Virtual field
	indexEntry := m.GetIndexEntry()
	_ = indexEntry
	if _indexEntryErr := writeBuffer.WriteVirtual(ctx, "indexEntry", m.GetIndexEntry()); _indexEntryErr != nil {
		return errors.Wrap(_indexEntryErr, "Error serializing 'indexEntry' field")
	}

	if popErr := writeBuffer.PopContext("BACnetPriorityArray"); popErr != nil {
		return errors.Wrap(popErr, "Error popping for BACnetPriorityArray")
	}
	return nil
}

func (m *_BACnetPriorityArray) IsBACnetPriorityArray() {}

func (m *_BACnetPriorityArray) DeepCopy() any {
	return m.deepCopy()
}

func (m *_BACnetPriorityArray) deepCopy() *_BACnetPriorityArray {
	if m == nil {
		return nil
	}
	_BACnetPriorityArrayCopy := &_BACnetPriorityArray{
		utils.DeepCopy[BACnetApplicationTagUnsignedInteger](m.NumberOfDataElements),
		utils.DeepCopySlice[BACnetPriorityValue, BACnetPriorityValue](m.Data),
	}
	return _BACnetPriorityArrayCopy
}

func (m *_BACnetPriorityArray) String() string {
	if m == nil {
		return "<nil>"
	}
	wb := utils.NewWriteBufferBoxBased(
		utils.WithWriteBufferBoxBasedMergeSingleBoxes(),
		utils.WithWriteBufferBoxBasedOmitEmptyBoxes(),
		utils.WithWriteBufferBoxBasedPrintPosLengthFooter(),
	)
	if err := wb.WriteSerializable(context.Background(), m); err != nil {
		return err.Error()
	}
	return wb.GetBox().String()
}
