/*
 * 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.

// SecurityData is the corresponding interface of SecurityData
type SecurityData interface {
	SecurityDataContract
	SecurityDataRequirements
	fmt.Stringer
	utils.LengthAware
	utils.Serializable
	utils.Copyable
	// IsSecurityData is a marker method to prevent unintentional type checks (interfaces of same signature)
	IsSecurityData()
	// CreateBuilder creates a SecurityDataBuilder
	CreateSecurityDataBuilder() SecurityDataBuilder
}

// SecurityDataContract provides a set of functions which can be overwritten by a sub struct
type SecurityDataContract interface {
	// GetCommandTypeContainer returns CommandTypeContainer (property field)
	GetCommandTypeContainer() SecurityCommandTypeContainer
	// GetArgument returns Argument (property field)
	GetArgument() byte
	// GetCommandType returns CommandType (virtual field)
	GetCommandType() SecurityCommandType
	// IsSecurityData is a marker method to prevent unintentional type checks (interfaces of same signature)
	IsSecurityData()
	// CreateBuilder creates a SecurityDataBuilder
	CreateSecurityDataBuilder() SecurityDataBuilder
}

// SecurityDataRequirements provides a set of functions which need to be implemented by a sub struct
type SecurityDataRequirements interface {
	GetLengthInBits(ctx context.Context) uint16
	GetLengthInBytes(ctx context.Context) uint16
	// GetArgument returns Argument (discriminator field)
	GetArgument() byte
	// GetCommandType returns CommandType (discriminator field)
	GetCommandType() SecurityCommandType
}

// _SecurityData is the data-structure of this message
type _SecurityData struct {
	_SubType interface {
		SecurityDataContract
		SecurityDataRequirements
	}
	CommandTypeContainer SecurityCommandTypeContainer
	Argument             byte
}

var _ SecurityDataContract = (*_SecurityData)(nil)

// NewSecurityData factory function for _SecurityData
func NewSecurityData(commandTypeContainer SecurityCommandTypeContainer, argument byte) *_SecurityData {
	return &_SecurityData{CommandTypeContainer: commandTypeContainer, Argument: argument}
}

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

// SecurityDataBuilder is a builder for SecurityData
type SecurityDataBuilder interface {
	utils.Copyable
	// WithMandatoryFields adds all mandatory fields (convenience for using multiple builder calls)
	WithMandatoryFields(commandTypeContainer SecurityCommandTypeContainer, argument byte) SecurityDataBuilder
	// WithCommandTypeContainer adds CommandTypeContainer (property field)
	WithCommandTypeContainer(SecurityCommandTypeContainer) SecurityDataBuilder
	// WithArgument adds Argument (property field)
	WithArgument(byte) SecurityDataBuilder
	// AsSecurityDataSystemArmedDisarmed converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataSystemArmedDisarmed() SecurityDataSystemArmedDisarmedBuilder
	// AsSecurityDataSystemDisarmed converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataSystemDisarmed() SecurityDataSystemDisarmedBuilder
	// AsSecurityDataExitDelayStarted converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataExitDelayStarted() SecurityDataExitDelayStartedBuilder
	// AsSecurityDataEntryDelayStarted converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataEntryDelayStarted() SecurityDataEntryDelayStartedBuilder
	// AsSecurityDataAlarmOn converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataAlarmOn() SecurityDataAlarmOnBuilder
	// AsSecurityDataAlarmOff converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataAlarmOff() SecurityDataAlarmOffBuilder
	// AsSecurityDataTamperOn converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataTamperOn() SecurityDataTamperOnBuilder
	// AsSecurityDataTamperOff converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataTamperOff() SecurityDataTamperOffBuilder
	// AsSecurityDataPanicActivated converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataPanicActivated() SecurityDataPanicActivatedBuilder
	// AsSecurityDataPanicCleared converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataPanicCleared() SecurityDataPanicClearedBuilder
	// AsSecurityDataZoneUnsealed converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataZoneUnsealed() SecurityDataZoneUnsealedBuilder
	// AsSecurityDataZoneSealed converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataZoneSealed() SecurityDataZoneSealedBuilder
	// AsSecurityDataZoneOpen converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataZoneOpen() SecurityDataZoneOpenBuilder
	// AsSecurityDataZoneShort converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataZoneShort() SecurityDataZoneShortBuilder
	// AsSecurityDataZoneIsolated converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataZoneIsolated() SecurityDataZoneIsolatedBuilder
	// AsSecurityDataLowBatteryDetected converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataLowBatteryDetected() SecurityDataLowBatteryDetectedBuilder
	// AsSecurityDataLowBatteryCorrected converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataLowBatteryCorrected() SecurityDataLowBatteryCorrectedBuilder
	// AsSecurityDataLowBatteryCharging converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataLowBatteryCharging() SecurityDataLowBatteryChargingBuilder
	// AsSecurityDataZoneName converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataZoneName() SecurityDataZoneNameBuilder
	// AsSecurityDataStatusReport1 converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataStatusReport1() SecurityDataStatusReport1Builder
	// AsSecurityDataStatusReport2 converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataStatusReport2() SecurityDataStatusReport2Builder
	// AsSecurityDataPasswordEntryStatus converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataPasswordEntryStatus() SecurityDataPasswordEntryStatusBuilder
	// AsSecurityDataMainsFailure converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataMainsFailure() SecurityDataMainsFailureBuilder
	// AsSecurityDataMainsRestoredOrApplied converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataMainsRestoredOrApplied() SecurityDataMainsRestoredOrAppliedBuilder
	// AsSecurityDataArmReadyNotReady converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataArmReadyNotReady() SecurityDataArmReadyNotReadyBuilder
	// AsSecurityDataCurrentAlarmType converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataCurrentAlarmType() SecurityDataCurrentAlarmTypeBuilder
	// AsSecurityDataLineCutAlarmRaised converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataLineCutAlarmRaised() SecurityDataLineCutAlarmRaisedBuilder
	// AsSecurityDataLineCutAlarmCleared converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataLineCutAlarmCleared() SecurityDataLineCutAlarmClearedBuilder
	// AsSecurityDataArmFailedRaised converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataArmFailedRaised() SecurityDataArmFailedRaisedBuilder
	// AsSecurityDataArmFailedCleared converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataArmFailedCleared() SecurityDataArmFailedClearedBuilder
	// AsSecurityDataFireAlarmRaised converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataFireAlarmRaised() SecurityDataFireAlarmRaisedBuilder
	// AsSecurityDataFireAlarmCleared converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataFireAlarmCleared() SecurityDataFireAlarmClearedBuilder
	// AsSecurityDataGasAlarmRaised converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataGasAlarmRaised() SecurityDataGasAlarmRaisedBuilder
	// AsSecurityDataGasAlarmCleared converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataGasAlarmCleared() SecurityDataGasAlarmClearedBuilder
	// AsSecurityDataOtherAlarmRaised converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataOtherAlarmRaised() SecurityDataOtherAlarmRaisedBuilder
	// AsSecurityDataOtherAlarmCleared converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataOtherAlarmCleared() SecurityDataOtherAlarmClearedBuilder
	// AsSecurityDataStatus1Request converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataStatus1Request() SecurityDataStatus1RequestBuilder
	// AsSecurityDataStatus2Request converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataStatus2Request() SecurityDataStatus2RequestBuilder
	// AsSecurityDataArmSystem converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataArmSystem() SecurityDataArmSystemBuilder
	// AsSecurityDataRaiseTamper converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataRaiseTamper() SecurityDataRaiseTamperBuilder
	// AsSecurityDataDropTamper converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataDropTamper() SecurityDataDropTamperBuilder
	// AsSecurityDataRaiseAlarm converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataRaiseAlarm() SecurityDataRaiseAlarmBuilder
	// AsSecurityDataEmulatedKeypad converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataEmulatedKeypad() SecurityDataEmulatedKeypadBuilder
	// AsSecurityDataDisplayMessage converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataDisplayMessage() SecurityDataDisplayMessageBuilder
	// AsSecurityDataRequestZoneName converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataRequestZoneName() SecurityDataRequestZoneNameBuilder
	// AsSecurityDataOff converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataOff() SecurityDataOffBuilder
	// AsSecurityDataOn converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataOn() SecurityDataOnBuilder
	// AsSecurityDataEvent converts this build to a subType of SecurityData. It is always possible to return to current builder using Done()
	AsSecurityDataEvent() SecurityDataEventBuilder
	// Build builds the SecurityData or returns an error if something is wrong
	PartialBuild() (SecurityDataContract, error)
	// MustBuild does the same as Build but panics on error
	PartialMustBuild() SecurityDataContract
	// Build builds the SecurityData or returns an error if something is wrong
	Build() (SecurityData, error)
	// MustBuild does the same as Build but panics on error
	MustBuild() SecurityData
}

// NewSecurityDataBuilder() creates a SecurityDataBuilder
func NewSecurityDataBuilder() SecurityDataBuilder {
	return &_SecurityDataBuilder{_SecurityData: new(_SecurityData)}
}

type _SecurityDataChildBuilder interface {
	utils.Copyable
	setParent(SecurityDataContract)
	buildForSecurityData() (SecurityData, error)
}

type _SecurityDataBuilder struct {
	*_SecurityData

	childBuilder _SecurityDataChildBuilder

	collectedErr []error
}

var _ (SecurityDataBuilder) = (*_SecurityDataBuilder)(nil)

func (b *_SecurityDataBuilder) WithMandatoryFields(commandTypeContainer SecurityCommandTypeContainer, argument byte) SecurityDataBuilder {
	return b.WithCommandTypeContainer(commandTypeContainer).WithArgument(argument)
}

func (b *_SecurityDataBuilder) WithCommandTypeContainer(commandTypeContainer SecurityCommandTypeContainer) SecurityDataBuilder {
	b.CommandTypeContainer = commandTypeContainer
	return b
}

func (b *_SecurityDataBuilder) WithArgument(argument byte) SecurityDataBuilder {
	b.Argument = argument
	return b
}

func (b *_SecurityDataBuilder) PartialBuild() (SecurityDataContract, error) {
	if err := stdErrors.Join(b.collectedErr...); err != nil {
		return nil, errors.Wrap(err, "error occurred during build")
	}
	return b._SecurityData.deepCopy(), nil
}

func (b *_SecurityDataBuilder) PartialMustBuild() SecurityDataContract {
	build, err := b.PartialBuild()
	if err != nil {
		panic(err)
	}
	return build
}

func (b *_SecurityDataBuilder) AsSecurityDataSystemArmedDisarmed() SecurityDataSystemArmedDisarmedBuilder {
	if cb, ok := b.childBuilder.(SecurityDataSystemArmedDisarmedBuilder); ok {
		return cb
	}
	cb := NewSecurityDataSystemArmedDisarmedBuilder().(*_SecurityDataSystemArmedDisarmedBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataSystemDisarmed() SecurityDataSystemDisarmedBuilder {
	if cb, ok := b.childBuilder.(SecurityDataSystemDisarmedBuilder); ok {
		return cb
	}
	cb := NewSecurityDataSystemDisarmedBuilder().(*_SecurityDataSystemDisarmedBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataExitDelayStarted() SecurityDataExitDelayStartedBuilder {
	if cb, ok := b.childBuilder.(SecurityDataExitDelayStartedBuilder); ok {
		return cb
	}
	cb := NewSecurityDataExitDelayStartedBuilder().(*_SecurityDataExitDelayStartedBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataEntryDelayStarted() SecurityDataEntryDelayStartedBuilder {
	if cb, ok := b.childBuilder.(SecurityDataEntryDelayStartedBuilder); ok {
		return cb
	}
	cb := NewSecurityDataEntryDelayStartedBuilder().(*_SecurityDataEntryDelayStartedBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataAlarmOn() SecurityDataAlarmOnBuilder {
	if cb, ok := b.childBuilder.(SecurityDataAlarmOnBuilder); ok {
		return cb
	}
	cb := NewSecurityDataAlarmOnBuilder().(*_SecurityDataAlarmOnBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataAlarmOff() SecurityDataAlarmOffBuilder {
	if cb, ok := b.childBuilder.(SecurityDataAlarmOffBuilder); ok {
		return cb
	}
	cb := NewSecurityDataAlarmOffBuilder().(*_SecurityDataAlarmOffBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataTamperOn() SecurityDataTamperOnBuilder {
	if cb, ok := b.childBuilder.(SecurityDataTamperOnBuilder); ok {
		return cb
	}
	cb := NewSecurityDataTamperOnBuilder().(*_SecurityDataTamperOnBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataTamperOff() SecurityDataTamperOffBuilder {
	if cb, ok := b.childBuilder.(SecurityDataTamperOffBuilder); ok {
		return cb
	}
	cb := NewSecurityDataTamperOffBuilder().(*_SecurityDataTamperOffBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataPanicActivated() SecurityDataPanicActivatedBuilder {
	if cb, ok := b.childBuilder.(SecurityDataPanicActivatedBuilder); ok {
		return cb
	}
	cb := NewSecurityDataPanicActivatedBuilder().(*_SecurityDataPanicActivatedBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataPanicCleared() SecurityDataPanicClearedBuilder {
	if cb, ok := b.childBuilder.(SecurityDataPanicClearedBuilder); ok {
		return cb
	}
	cb := NewSecurityDataPanicClearedBuilder().(*_SecurityDataPanicClearedBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataZoneUnsealed() SecurityDataZoneUnsealedBuilder {
	if cb, ok := b.childBuilder.(SecurityDataZoneUnsealedBuilder); ok {
		return cb
	}
	cb := NewSecurityDataZoneUnsealedBuilder().(*_SecurityDataZoneUnsealedBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataZoneSealed() SecurityDataZoneSealedBuilder {
	if cb, ok := b.childBuilder.(SecurityDataZoneSealedBuilder); ok {
		return cb
	}
	cb := NewSecurityDataZoneSealedBuilder().(*_SecurityDataZoneSealedBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataZoneOpen() SecurityDataZoneOpenBuilder {
	if cb, ok := b.childBuilder.(SecurityDataZoneOpenBuilder); ok {
		return cb
	}
	cb := NewSecurityDataZoneOpenBuilder().(*_SecurityDataZoneOpenBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataZoneShort() SecurityDataZoneShortBuilder {
	if cb, ok := b.childBuilder.(SecurityDataZoneShortBuilder); ok {
		return cb
	}
	cb := NewSecurityDataZoneShortBuilder().(*_SecurityDataZoneShortBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataZoneIsolated() SecurityDataZoneIsolatedBuilder {
	if cb, ok := b.childBuilder.(SecurityDataZoneIsolatedBuilder); ok {
		return cb
	}
	cb := NewSecurityDataZoneIsolatedBuilder().(*_SecurityDataZoneIsolatedBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataLowBatteryDetected() SecurityDataLowBatteryDetectedBuilder {
	if cb, ok := b.childBuilder.(SecurityDataLowBatteryDetectedBuilder); ok {
		return cb
	}
	cb := NewSecurityDataLowBatteryDetectedBuilder().(*_SecurityDataLowBatteryDetectedBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataLowBatteryCorrected() SecurityDataLowBatteryCorrectedBuilder {
	if cb, ok := b.childBuilder.(SecurityDataLowBatteryCorrectedBuilder); ok {
		return cb
	}
	cb := NewSecurityDataLowBatteryCorrectedBuilder().(*_SecurityDataLowBatteryCorrectedBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataLowBatteryCharging() SecurityDataLowBatteryChargingBuilder {
	if cb, ok := b.childBuilder.(SecurityDataLowBatteryChargingBuilder); ok {
		return cb
	}
	cb := NewSecurityDataLowBatteryChargingBuilder().(*_SecurityDataLowBatteryChargingBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataZoneName() SecurityDataZoneNameBuilder {
	if cb, ok := b.childBuilder.(SecurityDataZoneNameBuilder); ok {
		return cb
	}
	cb := NewSecurityDataZoneNameBuilder().(*_SecurityDataZoneNameBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataStatusReport1() SecurityDataStatusReport1Builder {
	if cb, ok := b.childBuilder.(SecurityDataStatusReport1Builder); ok {
		return cb
	}
	cb := NewSecurityDataStatusReport1Builder().(*_SecurityDataStatusReport1Builder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataStatusReport2() SecurityDataStatusReport2Builder {
	if cb, ok := b.childBuilder.(SecurityDataStatusReport2Builder); ok {
		return cb
	}
	cb := NewSecurityDataStatusReport2Builder().(*_SecurityDataStatusReport2Builder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataPasswordEntryStatus() SecurityDataPasswordEntryStatusBuilder {
	if cb, ok := b.childBuilder.(SecurityDataPasswordEntryStatusBuilder); ok {
		return cb
	}
	cb := NewSecurityDataPasswordEntryStatusBuilder().(*_SecurityDataPasswordEntryStatusBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataMainsFailure() SecurityDataMainsFailureBuilder {
	if cb, ok := b.childBuilder.(SecurityDataMainsFailureBuilder); ok {
		return cb
	}
	cb := NewSecurityDataMainsFailureBuilder().(*_SecurityDataMainsFailureBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataMainsRestoredOrApplied() SecurityDataMainsRestoredOrAppliedBuilder {
	if cb, ok := b.childBuilder.(SecurityDataMainsRestoredOrAppliedBuilder); ok {
		return cb
	}
	cb := NewSecurityDataMainsRestoredOrAppliedBuilder().(*_SecurityDataMainsRestoredOrAppliedBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataArmReadyNotReady() SecurityDataArmReadyNotReadyBuilder {
	if cb, ok := b.childBuilder.(SecurityDataArmReadyNotReadyBuilder); ok {
		return cb
	}
	cb := NewSecurityDataArmReadyNotReadyBuilder().(*_SecurityDataArmReadyNotReadyBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataCurrentAlarmType() SecurityDataCurrentAlarmTypeBuilder {
	if cb, ok := b.childBuilder.(SecurityDataCurrentAlarmTypeBuilder); ok {
		return cb
	}
	cb := NewSecurityDataCurrentAlarmTypeBuilder().(*_SecurityDataCurrentAlarmTypeBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataLineCutAlarmRaised() SecurityDataLineCutAlarmRaisedBuilder {
	if cb, ok := b.childBuilder.(SecurityDataLineCutAlarmRaisedBuilder); ok {
		return cb
	}
	cb := NewSecurityDataLineCutAlarmRaisedBuilder().(*_SecurityDataLineCutAlarmRaisedBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataLineCutAlarmCleared() SecurityDataLineCutAlarmClearedBuilder {
	if cb, ok := b.childBuilder.(SecurityDataLineCutAlarmClearedBuilder); ok {
		return cb
	}
	cb := NewSecurityDataLineCutAlarmClearedBuilder().(*_SecurityDataLineCutAlarmClearedBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataArmFailedRaised() SecurityDataArmFailedRaisedBuilder {
	if cb, ok := b.childBuilder.(SecurityDataArmFailedRaisedBuilder); ok {
		return cb
	}
	cb := NewSecurityDataArmFailedRaisedBuilder().(*_SecurityDataArmFailedRaisedBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataArmFailedCleared() SecurityDataArmFailedClearedBuilder {
	if cb, ok := b.childBuilder.(SecurityDataArmFailedClearedBuilder); ok {
		return cb
	}
	cb := NewSecurityDataArmFailedClearedBuilder().(*_SecurityDataArmFailedClearedBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataFireAlarmRaised() SecurityDataFireAlarmRaisedBuilder {
	if cb, ok := b.childBuilder.(SecurityDataFireAlarmRaisedBuilder); ok {
		return cb
	}
	cb := NewSecurityDataFireAlarmRaisedBuilder().(*_SecurityDataFireAlarmRaisedBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataFireAlarmCleared() SecurityDataFireAlarmClearedBuilder {
	if cb, ok := b.childBuilder.(SecurityDataFireAlarmClearedBuilder); ok {
		return cb
	}
	cb := NewSecurityDataFireAlarmClearedBuilder().(*_SecurityDataFireAlarmClearedBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataGasAlarmRaised() SecurityDataGasAlarmRaisedBuilder {
	if cb, ok := b.childBuilder.(SecurityDataGasAlarmRaisedBuilder); ok {
		return cb
	}
	cb := NewSecurityDataGasAlarmRaisedBuilder().(*_SecurityDataGasAlarmRaisedBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataGasAlarmCleared() SecurityDataGasAlarmClearedBuilder {
	if cb, ok := b.childBuilder.(SecurityDataGasAlarmClearedBuilder); ok {
		return cb
	}
	cb := NewSecurityDataGasAlarmClearedBuilder().(*_SecurityDataGasAlarmClearedBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataOtherAlarmRaised() SecurityDataOtherAlarmRaisedBuilder {
	if cb, ok := b.childBuilder.(SecurityDataOtherAlarmRaisedBuilder); ok {
		return cb
	}
	cb := NewSecurityDataOtherAlarmRaisedBuilder().(*_SecurityDataOtherAlarmRaisedBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataOtherAlarmCleared() SecurityDataOtherAlarmClearedBuilder {
	if cb, ok := b.childBuilder.(SecurityDataOtherAlarmClearedBuilder); ok {
		return cb
	}
	cb := NewSecurityDataOtherAlarmClearedBuilder().(*_SecurityDataOtherAlarmClearedBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataStatus1Request() SecurityDataStatus1RequestBuilder {
	if cb, ok := b.childBuilder.(SecurityDataStatus1RequestBuilder); ok {
		return cb
	}
	cb := NewSecurityDataStatus1RequestBuilder().(*_SecurityDataStatus1RequestBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataStatus2Request() SecurityDataStatus2RequestBuilder {
	if cb, ok := b.childBuilder.(SecurityDataStatus2RequestBuilder); ok {
		return cb
	}
	cb := NewSecurityDataStatus2RequestBuilder().(*_SecurityDataStatus2RequestBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataArmSystem() SecurityDataArmSystemBuilder {
	if cb, ok := b.childBuilder.(SecurityDataArmSystemBuilder); ok {
		return cb
	}
	cb := NewSecurityDataArmSystemBuilder().(*_SecurityDataArmSystemBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataRaiseTamper() SecurityDataRaiseTamperBuilder {
	if cb, ok := b.childBuilder.(SecurityDataRaiseTamperBuilder); ok {
		return cb
	}
	cb := NewSecurityDataRaiseTamperBuilder().(*_SecurityDataRaiseTamperBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataDropTamper() SecurityDataDropTamperBuilder {
	if cb, ok := b.childBuilder.(SecurityDataDropTamperBuilder); ok {
		return cb
	}
	cb := NewSecurityDataDropTamperBuilder().(*_SecurityDataDropTamperBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataRaiseAlarm() SecurityDataRaiseAlarmBuilder {
	if cb, ok := b.childBuilder.(SecurityDataRaiseAlarmBuilder); ok {
		return cb
	}
	cb := NewSecurityDataRaiseAlarmBuilder().(*_SecurityDataRaiseAlarmBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataEmulatedKeypad() SecurityDataEmulatedKeypadBuilder {
	if cb, ok := b.childBuilder.(SecurityDataEmulatedKeypadBuilder); ok {
		return cb
	}
	cb := NewSecurityDataEmulatedKeypadBuilder().(*_SecurityDataEmulatedKeypadBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataDisplayMessage() SecurityDataDisplayMessageBuilder {
	if cb, ok := b.childBuilder.(SecurityDataDisplayMessageBuilder); ok {
		return cb
	}
	cb := NewSecurityDataDisplayMessageBuilder().(*_SecurityDataDisplayMessageBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataRequestZoneName() SecurityDataRequestZoneNameBuilder {
	if cb, ok := b.childBuilder.(SecurityDataRequestZoneNameBuilder); ok {
		return cb
	}
	cb := NewSecurityDataRequestZoneNameBuilder().(*_SecurityDataRequestZoneNameBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataOff() SecurityDataOffBuilder {
	if cb, ok := b.childBuilder.(SecurityDataOffBuilder); ok {
		return cb
	}
	cb := NewSecurityDataOffBuilder().(*_SecurityDataOffBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataOn() SecurityDataOnBuilder {
	if cb, ok := b.childBuilder.(SecurityDataOnBuilder); ok {
		return cb
	}
	cb := NewSecurityDataOnBuilder().(*_SecurityDataOnBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) AsSecurityDataEvent() SecurityDataEventBuilder {
	if cb, ok := b.childBuilder.(SecurityDataEventBuilder); ok {
		return cb
	}
	cb := NewSecurityDataEventBuilder().(*_SecurityDataEventBuilder)
	cb.parentBuilder = b
	b.childBuilder = cb
	return cb
}

func (b *_SecurityDataBuilder) Build() (SecurityData, error) {
	v, err := b.PartialBuild()
	if err != nil {
		return nil, errors.Wrap(err, "error occurred during partial build")
	}
	if b.childBuilder == nil {
		return nil, errors.New("no child builder present")
	}
	b.childBuilder.setParent(v)
	return b.childBuilder.buildForSecurityData()
}

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

func (b *_SecurityDataBuilder) DeepCopy() any {
	_copy := b.CreateSecurityDataBuilder().(*_SecurityDataBuilder)
	_copy.childBuilder = b.childBuilder.DeepCopy().(_SecurityDataChildBuilder)
	_copy.childBuilder.setParent(_copy)
	if b.collectedErr != nil {
		copy(_copy.collectedErr, b.collectedErr)
	}
	return _copy
}

// CreateSecurityDataBuilder creates a SecurityDataBuilder
func (b *_SecurityData) CreateSecurityDataBuilder() SecurityDataBuilder {
	if b == nil {
		return NewSecurityDataBuilder()
	}
	return &_SecurityDataBuilder{_SecurityData: b.deepCopy()}
}

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

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

func (m *_SecurityData) GetCommandTypeContainer() SecurityCommandTypeContainer {
	return m.CommandTypeContainer
}

func (m *_SecurityData) GetArgument() byte {
	return m.Argument
}

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

func (pm *_SecurityData) GetCommandType() SecurityCommandType {
	m := pm._SubType
	ctx := context.Background()
	_ = ctx
	return CastSecurityCommandType(m.GetCommandTypeContainer().CommandType())
}

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

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

func (m *_SecurityData) GetTypeName() string {
	return "SecurityData"
}

func (m *_SecurityData) getLengthInBits(ctx context.Context) uint16 {
	lengthInBits := uint16(0)

	// Simple field (commandTypeContainer)
	lengthInBits += 8

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

	// Simple field (argument)
	lengthInBits += 8

	return lengthInBits
}

func (m *_SecurityData) GetLengthInBits(ctx context.Context) uint16 {
	return m._SubType.GetLengthInBits(ctx)
}

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

func SecurityDataParse[T SecurityData](ctx context.Context, theBytes []byte) (T, error) {
	return SecurityDataParseWithBuffer[T](ctx, utils.NewReadBufferByteBased(theBytes))
}

func SecurityDataParseWithBufferProducer[T SecurityData]() func(ctx context.Context, readBuffer utils.ReadBuffer) (T, error) {
	return func(ctx context.Context, readBuffer utils.ReadBuffer) (T, error) {
		v, err := SecurityDataParseWithBuffer[T](ctx, readBuffer)
		if err != nil {
			var zero T
			return zero, err
		}
		return v, nil
	}
}

func SecurityDataParseWithBuffer[T SecurityData](ctx context.Context, readBuffer utils.ReadBuffer) (T, error) {
	v, err := (new(_SecurityData)).parse(ctx, readBuffer)
	if err != nil {
		var zero T
		return zero, err
	}
	vc, ok := v.(T)
	if !ok {
		var zero T
		return zero, errors.Errorf("Unexpected type %T. Expected type %T", v, *new(T))
	}
	return vc, nil
}

func (m *_SecurityData) parse(ctx context.Context, readBuffer utils.ReadBuffer) (__securityData SecurityData, err error) {
	positionAware := readBuffer
	_ = positionAware
	if pullErr := readBuffer.PullContext("SecurityData"); pullErr != nil {
		return nil, errors.Wrap(pullErr, "Error pulling for SecurityData")
	}
	currentPos := positionAware.GetPos()
	_ = currentPos

	// Validation
	if !(KnowsSecurityCommandTypeContainer(ctx, readBuffer)) {
		return nil, errors.WithStack(utils.ParseAssertError{Message: "no command type could be found"})
	}

	commandTypeContainer, err := ReadEnumField[SecurityCommandTypeContainer](ctx, "commandTypeContainer", "SecurityCommandTypeContainer", ReadEnum(SecurityCommandTypeContainerByValue, ReadUnsignedByte(readBuffer, uint8(8))))
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'commandTypeContainer' field"))
	}
	m.CommandTypeContainer = commandTypeContainer

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

	argument, err := ReadSimpleField(ctx, "argument", ReadByte(readBuffer, 8))
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'argument' field"))
	}
	m.Argument = argument

	// Switch Field (Depending on the discriminator values, passes the instantiation to a sub-type)
	var _child SecurityData
	switch {
	case commandType == SecurityCommandType_ON && argument == 0x80: // SecurityDataSystemArmedDisarmed
		if _child, err = new(_SecurityDataSystemArmedDisarmed).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataSystemArmedDisarmed for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_OFF && argument == 0x80: // SecurityDataSystemDisarmed
		if _child, err = new(_SecurityDataSystemDisarmed).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataSystemDisarmed for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_EVENT && argument == 0x81: // SecurityDataExitDelayStarted
		if _child, err = new(_SecurityDataExitDelayStarted).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataExitDelayStarted for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_EVENT && argument == 0x82: // SecurityDataEntryDelayStarted
		if _child, err = new(_SecurityDataEntryDelayStarted).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataEntryDelayStarted for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_ON && argument == 0x83: // SecurityDataAlarmOn
		if _child, err = new(_SecurityDataAlarmOn).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataAlarmOn for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_OFF && argument == 0x83: // SecurityDataAlarmOff
		if _child, err = new(_SecurityDataAlarmOff).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataAlarmOff for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_ON && argument == 0x84: // SecurityDataTamperOn
		if _child, err = new(_SecurityDataTamperOn).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataTamperOn for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_OFF && argument == 0x84: // SecurityDataTamperOff
		if _child, err = new(_SecurityDataTamperOff).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataTamperOff for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_ON && argument == 0x85: // SecurityDataPanicActivated
		if _child, err = new(_SecurityDataPanicActivated).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataPanicActivated for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_OFF && argument == 0x85: // SecurityDataPanicCleared
		if _child, err = new(_SecurityDataPanicCleared).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataPanicCleared for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_EVENT && argument == 0x86: // SecurityDataZoneUnsealed
		if _child, err = new(_SecurityDataZoneUnsealed).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataZoneUnsealed for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_EVENT && argument == 0x87: // SecurityDataZoneSealed
		if _child, err = new(_SecurityDataZoneSealed).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataZoneSealed for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_EVENT && argument == 0x88: // SecurityDataZoneOpen
		if _child, err = new(_SecurityDataZoneOpen).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataZoneOpen for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_EVENT && argument == 0x89: // SecurityDataZoneShort
		if _child, err = new(_SecurityDataZoneShort).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataZoneShort for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_EVENT && argument == 0x89: // SecurityDataZoneIsolated
		if _child, err = new(_SecurityDataZoneIsolated).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataZoneIsolated for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_ON && argument == 0x8B: // SecurityDataLowBatteryDetected
		if _child, err = new(_SecurityDataLowBatteryDetected).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataLowBatteryDetected for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_OFF && argument == 0x8B: // SecurityDataLowBatteryCorrected
		if _child, err = new(_SecurityDataLowBatteryCorrected).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataLowBatteryCorrected for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_EVENT && argument == 0x8C: // SecurityDataLowBatteryCharging
		if _child, err = new(_SecurityDataLowBatteryCharging).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataLowBatteryCharging for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_EVENT && argument == 0x8D: // SecurityDataZoneName
		if _child, err = new(_SecurityDataZoneName).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataZoneName for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_EVENT && argument == 0x8E: // SecurityDataStatusReport1
		if _child, err = new(_SecurityDataStatusReport1).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataStatusReport1 for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_EVENT && argument == 0x8F: // SecurityDataStatusReport2
		if _child, err = new(_SecurityDataStatusReport2).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataStatusReport2 for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_EVENT && argument == 0x90: // SecurityDataPasswordEntryStatus
		if _child, err = new(_SecurityDataPasswordEntryStatus).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataPasswordEntryStatus for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_ON && argument == 0x91: // SecurityDataMainsFailure
		if _child, err = new(_SecurityDataMainsFailure).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataMainsFailure for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_OFF && argument == 0x91: // SecurityDataMainsRestoredOrApplied
		if _child, err = new(_SecurityDataMainsRestoredOrApplied).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataMainsRestoredOrApplied for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_EVENT && argument == 0x92: // SecurityDataArmReadyNotReady
		if _child, err = new(_SecurityDataArmReadyNotReady).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataArmReadyNotReady for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_EVENT && argument == 0x93: // SecurityDataCurrentAlarmType
		if _child, err = new(_SecurityDataCurrentAlarmType).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataCurrentAlarmType for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_ON && argument == 0x94: // SecurityDataLineCutAlarmRaised
		if _child, err = new(_SecurityDataLineCutAlarmRaised).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataLineCutAlarmRaised for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_OFF && argument == 0x94: // SecurityDataLineCutAlarmCleared
		if _child, err = new(_SecurityDataLineCutAlarmCleared).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataLineCutAlarmCleared for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_ON && argument == 0x95: // SecurityDataArmFailedRaised
		if _child, err = new(_SecurityDataArmFailedRaised).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataArmFailedRaised for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_OFF && argument == 0x95: // SecurityDataArmFailedCleared
		if _child, err = new(_SecurityDataArmFailedCleared).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataArmFailedCleared for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_ON && argument == 0x96: // SecurityDataFireAlarmRaised
		if _child, err = new(_SecurityDataFireAlarmRaised).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataFireAlarmRaised for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_OFF && argument == 0x96: // SecurityDataFireAlarmCleared
		if _child, err = new(_SecurityDataFireAlarmCleared).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataFireAlarmCleared for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_ON && argument == 0x97: // SecurityDataGasAlarmRaised
		if _child, err = new(_SecurityDataGasAlarmRaised).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataGasAlarmRaised for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_OFF && argument == 0x97: // SecurityDataGasAlarmCleared
		if _child, err = new(_SecurityDataGasAlarmCleared).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataGasAlarmCleared for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_ON && argument == 0x98: // SecurityDataOtherAlarmRaised
		if _child, err = new(_SecurityDataOtherAlarmRaised).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataOtherAlarmRaised for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_OFF && argument == 0x98: // SecurityDataOtherAlarmCleared
		if _child, err = new(_SecurityDataOtherAlarmCleared).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataOtherAlarmCleared for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_EVENT && argument == 0xA0: // SecurityDataStatus1Request
		if _child, err = new(_SecurityDataStatus1Request).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataStatus1Request for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_EVENT && argument == 0xA1: // SecurityDataStatus2Request
		if _child, err = new(_SecurityDataStatus2Request).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataStatus2Request for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_EVENT && argument == 0xA2: // SecurityDataArmSystem
		if _child, err = new(_SecurityDataArmSystem).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataArmSystem for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_ON && argument == 0xA3: // SecurityDataRaiseTamper
		if _child, err = new(_SecurityDataRaiseTamper).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataRaiseTamper for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_OFF && argument == 0xA3: // SecurityDataDropTamper
		if _child, err = new(_SecurityDataDropTamper).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataDropTamper for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_ON && argument == 0xA4: // SecurityDataRaiseAlarm
		if _child, err = new(_SecurityDataRaiseAlarm).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataRaiseAlarm for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_EVENT && argument == 0xA5: // SecurityDataEmulatedKeypad
		if _child, err = new(_SecurityDataEmulatedKeypad).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataEmulatedKeypad for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_ON && argument == 0xA6: // SecurityDataDisplayMessage
		if _child, err = new(_SecurityDataDisplayMessage).parse(ctx, readBuffer, m, commandTypeContainer); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataDisplayMessage for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_EVENT && argument == 0xA7: // SecurityDataRequestZoneName
		if _child, err = new(_SecurityDataRequestZoneName).parse(ctx, readBuffer, m); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataRequestZoneName for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_OFF: // SecurityDataOff
		if _child, err = new(_SecurityDataOff).parse(ctx, readBuffer, m, commandTypeContainer); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataOff for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_ON: // SecurityDataOn
		if _child, err = new(_SecurityDataOn).parse(ctx, readBuffer, m, commandTypeContainer); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataOn for type-switch of SecurityData")
		}
	case commandType == SecurityCommandType_EVENT: // SecurityDataEvent
		if _child, err = new(_SecurityDataEvent).parse(ctx, readBuffer, m, commandTypeContainer); err != nil {
			return nil, errors.Wrap(err, "Error parsing sub-type SecurityDataEvent for type-switch of SecurityData")
		}
	default:
		return nil, errors.Errorf("Unmapped type for parameters [commandType=%v, argument=%v]", commandType, argument)
	}

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

	return _child, nil
}

func (pm *_SecurityData) serializeParent(ctx context.Context, writeBuffer utils.WriteBuffer, child SecurityData, serializeChildFunction func() error) error {
	// We redirect all calls through client as some methods are only implemented there
	m := child
	_ = m
	positionAware := writeBuffer
	_ = positionAware
	log := zerolog.Ctx(ctx)
	_ = log
	if pushErr := writeBuffer.PushContext("SecurityData"); pushErr != nil {
		return errors.Wrap(pushErr, "Error pushing for SecurityData")
	}

	if err := WriteSimpleEnumField[SecurityCommandTypeContainer](ctx, "commandTypeContainer", "SecurityCommandTypeContainer", m.GetCommandTypeContainer(), WriteEnum[SecurityCommandTypeContainer, uint8](SecurityCommandTypeContainer.GetValue, SecurityCommandTypeContainer.PLC4XEnumName, WriteUnsignedByte(writeBuffer, 8))); err != nil {
		return errors.Wrap(err, "Error serializing 'commandTypeContainer' field")
	}
	// Virtual field
	commandType := m.GetCommandType()
	_ = commandType
	if _commandTypeErr := writeBuffer.WriteVirtual(ctx, "commandType", m.GetCommandType()); _commandTypeErr != nil {
		return errors.Wrap(_commandTypeErr, "Error serializing 'commandType' field")
	}

	if err := WriteSimpleField[byte](ctx, "argument", m.GetArgument(), WriteByte(writeBuffer, 8)); err != nil {
		return errors.Wrap(err, "Error serializing 'argument' field")
	}

	// Switch field (Depending on the discriminator values, passes the serialization to a sub-type)
	if _typeSwitchErr := serializeChildFunction(); _typeSwitchErr != nil {
		return errors.Wrap(_typeSwitchErr, "Error serializing sub-type field")
	}

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

func (m *_SecurityData) IsSecurityData() {}

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

func (m *_SecurityData) deepCopy() *_SecurityData {
	if m == nil {
		return nil
	}
	_SecurityDataCopy := &_SecurityData{
		nil, // will be set by child
		m.CommandTypeContainer,
		m.Argument,
	}
	return _SecurityDataCopy
}
