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

// Constant values.
const ModbusPDUReadDeviceIdentificationRequest_MEITYPE uint8 = 0x0E

// ModbusPDUReadDeviceIdentificationRequest is the corresponding interface of ModbusPDUReadDeviceIdentificationRequest
// Remark: Even if the Modbus spec states that supporting this type of request is mandatory
// I have not come across a single device that really supported it. Some devices just reacted
// with an error.
type ModbusPDUReadDeviceIdentificationRequest interface {
	fmt.Stringer
	utils.LengthAware
	utils.Serializable
	utils.Copyable
	ModbusPDU
	// GetLevel returns Level (property field)
	GetLevel() ModbusDeviceInformationLevel
	// GetObjectId returns ObjectId (property field)
	GetObjectId() uint8
	// IsModbusPDUReadDeviceIdentificationRequest is a marker method to prevent unintentional type checks (interfaces of same signature)
	IsModbusPDUReadDeviceIdentificationRequest()
	// CreateBuilder creates a ModbusPDUReadDeviceIdentificationRequestBuilder
	CreateModbusPDUReadDeviceIdentificationRequestBuilder() ModbusPDUReadDeviceIdentificationRequestBuilder
}

// _ModbusPDUReadDeviceIdentificationRequest is the data-structure of this message
type _ModbusPDUReadDeviceIdentificationRequest struct {
	ModbusPDUContract
	Level    ModbusDeviceInformationLevel
	ObjectId uint8
}

var _ ModbusPDUReadDeviceIdentificationRequest = (*_ModbusPDUReadDeviceIdentificationRequest)(nil)
var _ ModbusPDURequirements = (*_ModbusPDUReadDeviceIdentificationRequest)(nil)

// NewModbusPDUReadDeviceIdentificationRequest factory function for _ModbusPDUReadDeviceIdentificationRequest
func NewModbusPDUReadDeviceIdentificationRequest(level ModbusDeviceInformationLevel, objectId uint8) *_ModbusPDUReadDeviceIdentificationRequest {
	_result := &_ModbusPDUReadDeviceIdentificationRequest{
		ModbusPDUContract: NewModbusPDU(),
		Level:             level,
		ObjectId:          objectId,
	}
	_result.ModbusPDUContract.(*_ModbusPDU)._SubType = _result
	return _result
}

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

// ModbusPDUReadDeviceIdentificationRequestBuilder is a builder for ModbusPDUReadDeviceIdentificationRequest
type ModbusPDUReadDeviceIdentificationRequestBuilder interface {
	utils.Copyable
	// WithMandatoryFields adds all mandatory fields (convenience for using multiple builder calls)
	WithMandatoryFields(level ModbusDeviceInformationLevel, objectId uint8) ModbusPDUReadDeviceIdentificationRequestBuilder
	// WithLevel adds Level (property field)
	WithLevel(ModbusDeviceInformationLevel) ModbusPDUReadDeviceIdentificationRequestBuilder
	// WithObjectId adds ObjectId (property field)
	WithObjectId(uint8) ModbusPDUReadDeviceIdentificationRequestBuilder
	// Done is used to finish work on this child and return (or create one if none) to the parent builder
	Done() ModbusPDUBuilder
	// Build builds the ModbusPDUReadDeviceIdentificationRequest or returns an error if something is wrong
	Build() (ModbusPDUReadDeviceIdentificationRequest, error)
	// MustBuild does the same as Build but panics on error
	MustBuild() ModbusPDUReadDeviceIdentificationRequest
}

// NewModbusPDUReadDeviceIdentificationRequestBuilder() creates a ModbusPDUReadDeviceIdentificationRequestBuilder
func NewModbusPDUReadDeviceIdentificationRequestBuilder() ModbusPDUReadDeviceIdentificationRequestBuilder {
	return &_ModbusPDUReadDeviceIdentificationRequestBuilder{_ModbusPDUReadDeviceIdentificationRequest: new(_ModbusPDUReadDeviceIdentificationRequest)}
}

type _ModbusPDUReadDeviceIdentificationRequestBuilder struct {
	*_ModbusPDUReadDeviceIdentificationRequest

	parentBuilder *_ModbusPDUBuilder

	collectedErr []error
}

var _ (ModbusPDUReadDeviceIdentificationRequestBuilder) = (*_ModbusPDUReadDeviceIdentificationRequestBuilder)(nil)

func (b *_ModbusPDUReadDeviceIdentificationRequestBuilder) setParent(contract ModbusPDUContract) {
	b.ModbusPDUContract = contract
	contract.(*_ModbusPDU)._SubType = b._ModbusPDUReadDeviceIdentificationRequest
}

func (b *_ModbusPDUReadDeviceIdentificationRequestBuilder) WithMandatoryFields(level ModbusDeviceInformationLevel, objectId uint8) ModbusPDUReadDeviceIdentificationRequestBuilder {
	return b.WithLevel(level).WithObjectId(objectId)
}

func (b *_ModbusPDUReadDeviceIdentificationRequestBuilder) WithLevel(level ModbusDeviceInformationLevel) ModbusPDUReadDeviceIdentificationRequestBuilder {
	b.Level = level
	return b
}

func (b *_ModbusPDUReadDeviceIdentificationRequestBuilder) WithObjectId(objectId uint8) ModbusPDUReadDeviceIdentificationRequestBuilder {
	b.ObjectId = objectId
	return b
}

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

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

func (b *_ModbusPDUReadDeviceIdentificationRequestBuilder) Done() ModbusPDUBuilder {
	if b.parentBuilder == nil {
		b.parentBuilder = NewModbusPDUBuilder().(*_ModbusPDUBuilder)
	}
	return b.parentBuilder
}

func (b *_ModbusPDUReadDeviceIdentificationRequestBuilder) buildForModbusPDU() (ModbusPDU, error) {
	return b.Build()
}

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

// CreateModbusPDUReadDeviceIdentificationRequestBuilder creates a ModbusPDUReadDeviceIdentificationRequestBuilder
func (b *_ModbusPDUReadDeviceIdentificationRequest) CreateModbusPDUReadDeviceIdentificationRequestBuilder() ModbusPDUReadDeviceIdentificationRequestBuilder {
	if b == nil {
		return NewModbusPDUReadDeviceIdentificationRequestBuilder()
	}
	return &_ModbusPDUReadDeviceIdentificationRequestBuilder{_ModbusPDUReadDeviceIdentificationRequest: b.deepCopy()}
}

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

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

func (m *_ModbusPDUReadDeviceIdentificationRequest) GetErrorFlag() bool {
	return bool(false)
}

func (m *_ModbusPDUReadDeviceIdentificationRequest) GetFunctionFlag() uint8 {
	return 0x2B
}

func (m *_ModbusPDUReadDeviceIdentificationRequest) GetResponse() bool {
	return bool(false)
}

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

func (m *_ModbusPDUReadDeviceIdentificationRequest) GetParent() ModbusPDUContract {
	return m.ModbusPDUContract
}

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

func (m *_ModbusPDUReadDeviceIdentificationRequest) GetLevel() ModbusDeviceInformationLevel {
	return m.Level
}

func (m *_ModbusPDUReadDeviceIdentificationRequest) GetObjectId() uint8 {
	return m.ObjectId
}

///////////////////////
///////////////////////
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
/////////////////////// Accessors for const fields.
///////////////////////

func (m *_ModbusPDUReadDeviceIdentificationRequest) GetMeiType() uint8 {
	return ModbusPDUReadDeviceIdentificationRequest_MEITYPE
}

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

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

func (m *_ModbusPDUReadDeviceIdentificationRequest) GetTypeName() string {
	return "ModbusPDUReadDeviceIdentificationRequest"
}

func (m *_ModbusPDUReadDeviceIdentificationRequest) GetLengthInBits(ctx context.Context) uint16 {
	lengthInBits := uint16(m.ModbusPDUContract.(*_ModbusPDU).getLengthInBits(ctx))

	// Const Field (meiType)
	lengthInBits += 8

	// Simple field (level)
	lengthInBits += 8

	// Simple field (objectId)
	lengthInBits += 8

	return lengthInBits
}

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

func (m *_ModbusPDUReadDeviceIdentificationRequest) parse(ctx context.Context, readBuffer utils.ReadBuffer, parent *_ModbusPDU, response bool) (__modbusPDUReadDeviceIdentificationRequest ModbusPDUReadDeviceIdentificationRequest, err error) {
	m.ModbusPDUContract = parent
	parent._SubType = m
	positionAware := readBuffer
	_ = positionAware
	if pullErr := readBuffer.PullContext("ModbusPDUReadDeviceIdentificationRequest"); pullErr != nil {
		return nil, errors.Wrap(pullErr, "Error pulling for ModbusPDUReadDeviceIdentificationRequest")
	}
	currentPos := positionAware.GetPos()
	_ = currentPos

	meiType, err := ReadConstField[uint8](ctx, "meiType", ReadUnsignedByte(readBuffer, uint8(8)), ModbusPDUReadDeviceIdentificationRequest_MEITYPE)
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'meiType' field"))
	}
	_ = meiType

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

	objectId, err := ReadSimpleField(ctx, "objectId", ReadUnsignedByte(readBuffer, uint8(8)))
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("Error parsing 'objectId' field"))
	}
	m.ObjectId = objectId

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

	return m, nil
}

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

		if err := WriteConstField(ctx, "meiType", ModbusPDUReadDeviceIdentificationRequest_MEITYPE, WriteUnsignedByte(writeBuffer, 8)); err != nil {
			return errors.Wrap(err, "Error serializing 'meiType' field")
		}

		if err := WriteSimpleEnumField[ModbusDeviceInformationLevel](ctx, "level", "ModbusDeviceInformationLevel", m.GetLevel(), WriteEnum[ModbusDeviceInformationLevel, uint8](ModbusDeviceInformationLevel.GetValue, ModbusDeviceInformationLevel.PLC4XEnumName, WriteUnsignedByte(writeBuffer, 8))); err != nil {
			return errors.Wrap(err, "Error serializing 'level' field")
		}

		if err := WriteSimpleField[uint8](ctx, "objectId", m.GetObjectId(), WriteUnsignedByte(writeBuffer, 8)); err != nil {
			return errors.Wrap(err, "Error serializing 'objectId' field")
		}

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

func (m *_ModbusPDUReadDeviceIdentificationRequest) IsModbusPDUReadDeviceIdentificationRequest() {}

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

func (m *_ModbusPDUReadDeviceIdentificationRequest) deepCopy() *_ModbusPDUReadDeviceIdentificationRequest {
	if m == nil {
		return nil
	}
	_ModbusPDUReadDeviceIdentificationRequestCopy := &_ModbusPDUReadDeviceIdentificationRequest{
		m.ModbusPDUContract.(*_ModbusPDU).deepCopy(),
		m.Level,
		m.ObjectId,
	}
	_ModbusPDUReadDeviceIdentificationRequestCopy.ModbusPDUContract.(*_ModbusPDU)._SubType = m
	return _ModbusPDUReadDeviceIdentificationRequestCopy
}

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