/*
 * 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/utils"
)

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

// ApduDataExtReadRoutingTableRequest is the corresponding interface of ApduDataExtReadRoutingTableRequest
type ApduDataExtReadRoutingTableRequest interface {
	fmt.Stringer
	utils.LengthAware
	utils.Serializable
	utils.Copyable
	ApduDataExt
	// IsApduDataExtReadRoutingTableRequest is a marker method to prevent unintentional type checks (interfaces of same signature)
	IsApduDataExtReadRoutingTableRequest()
	// CreateBuilder creates a ApduDataExtReadRoutingTableRequestBuilder
	CreateApduDataExtReadRoutingTableRequestBuilder() ApduDataExtReadRoutingTableRequestBuilder
}

// _ApduDataExtReadRoutingTableRequest is the data-structure of this message
type _ApduDataExtReadRoutingTableRequest struct {
	ApduDataExtContract
}

var _ ApduDataExtReadRoutingTableRequest = (*_ApduDataExtReadRoutingTableRequest)(nil)
var _ ApduDataExtRequirements = (*_ApduDataExtReadRoutingTableRequest)(nil)

// NewApduDataExtReadRoutingTableRequest factory function for _ApduDataExtReadRoutingTableRequest
func NewApduDataExtReadRoutingTableRequest() *_ApduDataExtReadRoutingTableRequest {
	_result := &_ApduDataExtReadRoutingTableRequest{
		ApduDataExtContract: NewApduDataExt(),
	}
	_result.ApduDataExtContract.(*_ApduDataExt)._SubType = _result
	return _result
}

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

// ApduDataExtReadRoutingTableRequestBuilder is a builder for ApduDataExtReadRoutingTableRequest
type ApduDataExtReadRoutingTableRequestBuilder interface {
	utils.Copyable
	// WithMandatoryFields adds all mandatory fields (convenience for using multiple builder calls)
	WithMandatoryFields() ApduDataExtReadRoutingTableRequestBuilder
	// Done is used to finish work on this child and return (or create one if none) to the parent builder
	Done() ApduDataExtBuilder
	// Build builds the ApduDataExtReadRoutingTableRequest or returns an error if something is wrong
	Build() (ApduDataExtReadRoutingTableRequest, error)
	// MustBuild does the same as Build but panics on error
	MustBuild() ApduDataExtReadRoutingTableRequest
}

// NewApduDataExtReadRoutingTableRequestBuilder() creates a ApduDataExtReadRoutingTableRequestBuilder
func NewApduDataExtReadRoutingTableRequestBuilder() ApduDataExtReadRoutingTableRequestBuilder {
	return &_ApduDataExtReadRoutingTableRequestBuilder{_ApduDataExtReadRoutingTableRequest: new(_ApduDataExtReadRoutingTableRequest)}
}

type _ApduDataExtReadRoutingTableRequestBuilder struct {
	*_ApduDataExtReadRoutingTableRequest

	parentBuilder *_ApduDataExtBuilder

	collectedErr []error
}

var _ (ApduDataExtReadRoutingTableRequestBuilder) = (*_ApduDataExtReadRoutingTableRequestBuilder)(nil)

func (b *_ApduDataExtReadRoutingTableRequestBuilder) setParent(contract ApduDataExtContract) {
	b.ApduDataExtContract = contract
	contract.(*_ApduDataExt)._SubType = b._ApduDataExtReadRoutingTableRequest
}

func (b *_ApduDataExtReadRoutingTableRequestBuilder) WithMandatoryFields() ApduDataExtReadRoutingTableRequestBuilder {
	return b
}

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

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

func (b *_ApduDataExtReadRoutingTableRequestBuilder) Done() ApduDataExtBuilder {
	if b.parentBuilder == nil {
		b.parentBuilder = NewApduDataExtBuilder().(*_ApduDataExtBuilder)
	}
	return b.parentBuilder
}

func (b *_ApduDataExtReadRoutingTableRequestBuilder) buildForApduDataExt() (ApduDataExt, error) {
	return b.Build()
}

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

// CreateApduDataExtReadRoutingTableRequestBuilder creates a ApduDataExtReadRoutingTableRequestBuilder
func (b *_ApduDataExtReadRoutingTableRequest) CreateApduDataExtReadRoutingTableRequestBuilder() ApduDataExtReadRoutingTableRequestBuilder {
	if b == nil {
		return NewApduDataExtReadRoutingTableRequestBuilder()
	}
	return &_ApduDataExtReadRoutingTableRequestBuilder{_ApduDataExtReadRoutingTableRequest: b.deepCopy()}
}

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

///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
/////////////////////// Accessors for discriminator values.
///////////////////////

func (m *_ApduDataExtReadRoutingTableRequest) GetExtApciType() uint8 {
	return 0x01
}

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

func (m *_ApduDataExtReadRoutingTableRequest) GetParent() ApduDataExtContract {
	return m.ApduDataExtContract
}

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

func (m *_ApduDataExtReadRoutingTableRequest) GetTypeName() string {
	return "ApduDataExtReadRoutingTableRequest"
}

func (m *_ApduDataExtReadRoutingTableRequest) GetLengthInBits(ctx context.Context) uint16 {
	lengthInBits := uint16(m.ApduDataExtContract.(*_ApduDataExt).getLengthInBits(ctx))

	return lengthInBits
}

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

func (m *_ApduDataExtReadRoutingTableRequest) parse(ctx context.Context, readBuffer utils.ReadBuffer, parent *_ApduDataExt, length uint8) (__apduDataExtReadRoutingTableRequest ApduDataExtReadRoutingTableRequest, err error) {
	m.ApduDataExtContract = parent
	parent._SubType = m
	positionAware := readBuffer
	_ = positionAware
	if pullErr := readBuffer.PullContext("ApduDataExtReadRoutingTableRequest"); pullErr != nil {
		return nil, errors.Wrap(pullErr, "Error pulling for ApduDataExtReadRoutingTableRequest")
	}
	currentPos := positionAware.GetPos()
	_ = currentPos

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

	return m, nil
}

func (m *_ApduDataExtReadRoutingTableRequest) 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 *_ApduDataExtReadRoutingTableRequest) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
	positionAware := writeBuffer
	_ = positionAware
	log := zerolog.Ctx(ctx)
	_ = log
	ser := func() error {
		if pushErr := writeBuffer.PushContext("ApduDataExtReadRoutingTableRequest"); pushErr != nil {
			return errors.Wrap(pushErr, "Error pushing for ApduDataExtReadRoutingTableRequest")
		}

		if popErr := writeBuffer.PopContext("ApduDataExtReadRoutingTableRequest"); popErr != nil {
			return errors.Wrap(popErr, "Error popping for ApduDataExtReadRoutingTableRequest")
		}
		return nil
	}
	return m.ApduDataExtContract.(*_ApduDataExt).serializeParent(ctx, writeBuffer, m, ser)
}

func (m *_ApduDataExtReadRoutingTableRequest) IsApduDataExtReadRoutingTableRequest() {}

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

func (m *_ApduDataExtReadRoutingTableRequest) deepCopy() *_ApduDataExtReadRoutingTableRequest {
	if m == nil {
		return nil
	}
	_ApduDataExtReadRoutingTableRequestCopy := &_ApduDataExtReadRoutingTableRequest{
		m.ApduDataExtContract.(*_ApduDataExt).deepCopy(),
	}
	_ApduDataExtReadRoutingTableRequestCopy.ApduDataExtContract.(*_ApduDataExt)._SubType = m
	return _ApduDataExtReadRoutingTableRequestCopy
}

func (m *_ApduDataExtReadRoutingTableRequest) 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()
}
