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

// Code generated by mockery v2.28.2. DO NOT EDIT.

package values

import (
	big "math/big"

	apivalues "github.com/apache/plc4x/plc4go/pkg/api/values"

	context "context"

	mock "github.com/stretchr/testify/mock"

	utils "github.com/apache/plc4x/plc4go/spi/utils"
)

// MockWriteBufferPlcValueBased is an autogenerated mock type for the WriteBufferPlcValueBased type
type MockWriteBufferPlcValueBased struct {
	mock.Mock
}

type MockWriteBufferPlcValueBased_Expecter struct {
	mock *mock.Mock
}

func (_m *MockWriteBufferPlcValueBased) EXPECT() *MockWriteBufferPlcValueBased_Expecter {
	return &MockWriteBufferPlcValueBased_Expecter{mock: &_m.Mock}
}

// GetPlcValue provides a mock function with given fields:
func (_m *MockWriteBufferPlcValueBased) GetPlcValue() apivalues.PlcValue {
	ret := _m.Called()

	var r0 apivalues.PlcValue
	if rf, ok := ret.Get(0).(func() apivalues.PlcValue); ok {
		r0 = rf()
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(apivalues.PlcValue)
		}
	}

	return r0
}

// MockWriteBufferPlcValueBased_GetPlcValue_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPlcValue'
type MockWriteBufferPlcValueBased_GetPlcValue_Call struct {
	*mock.Call
}

// GetPlcValue is a helper method to define mock.On call
func (_e *MockWriteBufferPlcValueBased_Expecter) GetPlcValue() *MockWriteBufferPlcValueBased_GetPlcValue_Call {
	return &MockWriteBufferPlcValueBased_GetPlcValue_Call{Call: _e.mock.On("GetPlcValue")}
}

func (_c *MockWriteBufferPlcValueBased_GetPlcValue_Call) Run(run func()) *MockWriteBufferPlcValueBased_GetPlcValue_Call {
	_c.Call.Run(func(args mock.Arguments) {
		run()
	})
	return _c
}

func (_c *MockWriteBufferPlcValueBased_GetPlcValue_Call) Return(_a0 apivalues.PlcValue) *MockWriteBufferPlcValueBased_GetPlcValue_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferPlcValueBased_GetPlcValue_Call) RunAndReturn(run func() apivalues.PlcValue) *MockWriteBufferPlcValueBased_GetPlcValue_Call {
	_c.Call.Return(run)
	return _c
}

// GetPos provides a mock function with given fields:
func (_m *MockWriteBufferPlcValueBased) GetPos() uint16 {
	ret := _m.Called()

	var r0 uint16
	if rf, ok := ret.Get(0).(func() uint16); ok {
		r0 = rf()
	} else {
		r0 = ret.Get(0).(uint16)
	}

	return r0
}

// MockWriteBufferPlcValueBased_GetPos_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPos'
type MockWriteBufferPlcValueBased_GetPos_Call struct {
	*mock.Call
}

// GetPos is a helper method to define mock.On call
func (_e *MockWriteBufferPlcValueBased_Expecter) GetPos() *MockWriteBufferPlcValueBased_GetPos_Call {
	return &MockWriteBufferPlcValueBased_GetPos_Call{Call: _e.mock.On("GetPos")}
}

func (_c *MockWriteBufferPlcValueBased_GetPos_Call) Run(run func()) *MockWriteBufferPlcValueBased_GetPos_Call {
	_c.Call.Run(func(args mock.Arguments) {
		run()
	})
	return _c
}

func (_c *MockWriteBufferPlcValueBased_GetPos_Call) Return(_a0 uint16) *MockWriteBufferPlcValueBased_GetPos_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferPlcValueBased_GetPos_Call) RunAndReturn(run func() uint16) *MockWriteBufferPlcValueBased_GetPos_Call {
	_c.Call.Return(run)
	return _c
}

// PopContext provides a mock function with given fields: logicalName, writerArgs
func (_m *MockWriteBufferPlcValueBased) PopContext(logicalName string, writerArgs ...utils.WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, ...utils.WithWriterArgs) error); ok {
		r0 = rf(logicalName, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferPlcValueBased_PopContext_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PopContext'
type MockWriteBufferPlcValueBased_PopContext_Call struct {
	*mock.Call
}

// PopContext is a helper method to define mock.On call
//   - logicalName string
//   - writerArgs ...utils.WithWriterArgs
func (_e *MockWriteBufferPlcValueBased_Expecter) PopContext(logicalName interface{}, writerArgs ...interface{}) *MockWriteBufferPlcValueBased_PopContext_Call {
	return &MockWriteBufferPlcValueBased_PopContext_Call{Call: _e.mock.On("PopContext",
		append([]interface{}{logicalName}, writerArgs...)...)}
}

func (_c *MockWriteBufferPlcValueBased_PopContext_Call) Run(run func(logicalName string, writerArgs ...utils.WithWriterArgs)) *MockWriteBufferPlcValueBased_PopContext_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]utils.WithWriterArgs, len(args)-1)
		for i, a := range args[1:] {
			if a != nil {
				variadicArgs[i] = a.(utils.WithWriterArgs)
			}
		}
		run(args[0].(string), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferPlcValueBased_PopContext_Call) Return(_a0 error) *MockWriteBufferPlcValueBased_PopContext_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferPlcValueBased_PopContext_Call) RunAndReturn(run func(string, ...utils.WithWriterArgs) error) *MockWriteBufferPlcValueBased_PopContext_Call {
	_c.Call.Return(run)
	return _c
}

// PushContext provides a mock function with given fields: logicalName, writerArgs
func (_m *MockWriteBufferPlcValueBased) PushContext(logicalName string, writerArgs ...utils.WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, ...utils.WithWriterArgs) error); ok {
		r0 = rf(logicalName, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferPlcValueBased_PushContext_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PushContext'
type MockWriteBufferPlcValueBased_PushContext_Call struct {
	*mock.Call
}

// PushContext is a helper method to define mock.On call
//   - logicalName string
//   - writerArgs ...utils.WithWriterArgs
func (_e *MockWriteBufferPlcValueBased_Expecter) PushContext(logicalName interface{}, writerArgs ...interface{}) *MockWriteBufferPlcValueBased_PushContext_Call {
	return &MockWriteBufferPlcValueBased_PushContext_Call{Call: _e.mock.On("PushContext",
		append([]interface{}{logicalName}, writerArgs...)...)}
}

func (_c *MockWriteBufferPlcValueBased_PushContext_Call) Run(run func(logicalName string, writerArgs ...utils.WithWriterArgs)) *MockWriteBufferPlcValueBased_PushContext_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]utils.WithWriterArgs, len(args)-1)
		for i, a := range args[1:] {
			if a != nil {
				variadicArgs[i] = a.(utils.WithWriterArgs)
			}
		}
		run(args[0].(string), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferPlcValueBased_PushContext_Call) Return(_a0 error) *MockWriteBufferPlcValueBased_PushContext_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferPlcValueBased_PushContext_Call) RunAndReturn(run func(string, ...utils.WithWriterArgs) error) *MockWriteBufferPlcValueBased_PushContext_Call {
	_c.Call.Return(run)
	return _c
}

// WriteBigFloat provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferPlcValueBased) WriteBigFloat(logicalName string, bitLength uint8, value *big.Float, writerArgs ...utils.WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint8, *big.Float, ...utils.WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferPlcValueBased_WriteBigFloat_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteBigFloat'
type MockWriteBufferPlcValueBased_WriteBigFloat_Call struct {
	*mock.Call
}

// WriteBigFloat is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - value *big.Float
//   - writerArgs ...utils.WithWriterArgs
func (_e *MockWriteBufferPlcValueBased_Expecter) WriteBigFloat(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferPlcValueBased_WriteBigFloat_Call {
	return &MockWriteBufferPlcValueBased_WriteBigFloat_Call{Call: _e.mock.On("WriteBigFloat",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferPlcValueBased_WriteBigFloat_Call) Run(run func(logicalName string, bitLength uint8, value *big.Float, writerArgs ...utils.WithWriterArgs)) *MockWriteBufferPlcValueBased_WriteBigFloat_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]utils.WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(utils.WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint8), args[2].(*big.Float), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteBigFloat_Call) Return(_a0 error) *MockWriteBufferPlcValueBased_WriteBigFloat_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteBigFloat_Call) RunAndReturn(run func(string, uint8, *big.Float, ...utils.WithWriterArgs) error) *MockWriteBufferPlcValueBased_WriteBigFloat_Call {
	_c.Call.Return(run)
	return _c
}

// WriteBigInt provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferPlcValueBased) WriteBigInt(logicalName string, bitLength uint8, value *big.Int, writerArgs ...utils.WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint8, *big.Int, ...utils.WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferPlcValueBased_WriteBigInt_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteBigInt'
type MockWriteBufferPlcValueBased_WriteBigInt_Call struct {
	*mock.Call
}

// WriteBigInt is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - value *big.Int
//   - writerArgs ...utils.WithWriterArgs
func (_e *MockWriteBufferPlcValueBased_Expecter) WriteBigInt(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferPlcValueBased_WriteBigInt_Call {
	return &MockWriteBufferPlcValueBased_WriteBigInt_Call{Call: _e.mock.On("WriteBigInt",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferPlcValueBased_WriteBigInt_Call) Run(run func(logicalName string, bitLength uint8, value *big.Int, writerArgs ...utils.WithWriterArgs)) *MockWriteBufferPlcValueBased_WriteBigInt_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]utils.WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(utils.WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint8), args[2].(*big.Int), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteBigInt_Call) Return(_a0 error) *MockWriteBufferPlcValueBased_WriteBigInt_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteBigInt_Call) RunAndReturn(run func(string, uint8, *big.Int, ...utils.WithWriterArgs) error) *MockWriteBufferPlcValueBased_WriteBigInt_Call {
	_c.Call.Return(run)
	return _c
}

// WriteBit provides a mock function with given fields: logicalName, value, writerArgs
func (_m *MockWriteBufferPlcValueBased) WriteBit(logicalName string, value bool, writerArgs ...utils.WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, bool, ...utils.WithWriterArgs) error); ok {
		r0 = rf(logicalName, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferPlcValueBased_WriteBit_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteBit'
type MockWriteBufferPlcValueBased_WriteBit_Call struct {
	*mock.Call
}

// WriteBit is a helper method to define mock.On call
//   - logicalName string
//   - value bool
//   - writerArgs ...utils.WithWriterArgs
func (_e *MockWriteBufferPlcValueBased_Expecter) WriteBit(logicalName interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferPlcValueBased_WriteBit_Call {
	return &MockWriteBufferPlcValueBased_WriteBit_Call{Call: _e.mock.On("WriteBit",
		append([]interface{}{logicalName, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferPlcValueBased_WriteBit_Call) Run(run func(logicalName string, value bool, writerArgs ...utils.WithWriterArgs)) *MockWriteBufferPlcValueBased_WriteBit_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]utils.WithWriterArgs, len(args)-2)
		for i, a := range args[2:] {
			if a != nil {
				variadicArgs[i] = a.(utils.WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(bool), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteBit_Call) Return(_a0 error) *MockWriteBufferPlcValueBased_WriteBit_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteBit_Call) RunAndReturn(run func(string, bool, ...utils.WithWriterArgs) error) *MockWriteBufferPlcValueBased_WriteBit_Call {
	_c.Call.Return(run)
	return _c
}

// WriteByte provides a mock function with given fields: logicalName, value, writerArgs
func (_m *MockWriteBufferPlcValueBased) WriteByte(logicalName string, value byte, writerArgs ...utils.WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, byte, ...utils.WithWriterArgs) error); ok {
		r0 = rf(logicalName, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferPlcValueBased_WriteByte_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteByte'
type MockWriteBufferPlcValueBased_WriteByte_Call struct {
	*mock.Call
}

// WriteByte is a helper method to define mock.On call
//   - logicalName string
//   - value byte
//   - writerArgs ...utils.WithWriterArgs
func (_e *MockWriteBufferPlcValueBased_Expecter) WriteByte(logicalName interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferPlcValueBased_WriteByte_Call {
	return &MockWriteBufferPlcValueBased_WriteByte_Call{Call: _e.mock.On("WriteByte",
		append([]interface{}{logicalName, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferPlcValueBased_WriteByte_Call) Run(run func(logicalName string, value byte, writerArgs ...utils.WithWriterArgs)) *MockWriteBufferPlcValueBased_WriteByte_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]utils.WithWriterArgs, len(args)-2)
		for i, a := range args[2:] {
			if a != nil {
				variadicArgs[i] = a.(utils.WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(byte), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteByte_Call) Return(_a0 error) *MockWriteBufferPlcValueBased_WriteByte_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteByte_Call) RunAndReturn(run func(string, byte, ...utils.WithWriterArgs) error) *MockWriteBufferPlcValueBased_WriteByte_Call {
	_c.Call.Return(run)
	return _c
}

// WriteByteArray provides a mock function with given fields: logicalName, data, writerArgs
func (_m *MockWriteBufferPlcValueBased) WriteByteArray(logicalName string, data []byte, writerArgs ...utils.WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, data)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, []byte, ...utils.WithWriterArgs) error); ok {
		r0 = rf(logicalName, data, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferPlcValueBased_WriteByteArray_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteByteArray'
type MockWriteBufferPlcValueBased_WriteByteArray_Call struct {
	*mock.Call
}

// WriteByteArray is a helper method to define mock.On call
//   - logicalName string
//   - data []byte
//   - writerArgs ...utils.WithWriterArgs
func (_e *MockWriteBufferPlcValueBased_Expecter) WriteByteArray(logicalName interface{}, data interface{}, writerArgs ...interface{}) *MockWriteBufferPlcValueBased_WriteByteArray_Call {
	return &MockWriteBufferPlcValueBased_WriteByteArray_Call{Call: _e.mock.On("WriteByteArray",
		append([]interface{}{logicalName, data}, writerArgs...)...)}
}

func (_c *MockWriteBufferPlcValueBased_WriteByteArray_Call) Run(run func(logicalName string, data []byte, writerArgs ...utils.WithWriterArgs)) *MockWriteBufferPlcValueBased_WriteByteArray_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]utils.WithWriterArgs, len(args)-2)
		for i, a := range args[2:] {
			if a != nil {
				variadicArgs[i] = a.(utils.WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].([]byte), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteByteArray_Call) Return(_a0 error) *MockWriteBufferPlcValueBased_WriteByteArray_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteByteArray_Call) RunAndReturn(run func(string, []byte, ...utils.WithWriterArgs) error) *MockWriteBufferPlcValueBased_WriteByteArray_Call {
	_c.Call.Return(run)
	return _c
}

// WriteFloat32 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferPlcValueBased) WriteFloat32(logicalName string, bitLength uint8, value float32, writerArgs ...utils.WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint8, float32, ...utils.WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferPlcValueBased_WriteFloat32_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteFloat32'
type MockWriteBufferPlcValueBased_WriteFloat32_Call struct {
	*mock.Call
}

// WriteFloat32 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - value float32
//   - writerArgs ...utils.WithWriterArgs
func (_e *MockWriteBufferPlcValueBased_Expecter) WriteFloat32(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferPlcValueBased_WriteFloat32_Call {
	return &MockWriteBufferPlcValueBased_WriteFloat32_Call{Call: _e.mock.On("WriteFloat32",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferPlcValueBased_WriteFloat32_Call) Run(run func(logicalName string, bitLength uint8, value float32, writerArgs ...utils.WithWriterArgs)) *MockWriteBufferPlcValueBased_WriteFloat32_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]utils.WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(utils.WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint8), args[2].(float32), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteFloat32_Call) Return(_a0 error) *MockWriteBufferPlcValueBased_WriteFloat32_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteFloat32_Call) RunAndReturn(run func(string, uint8, float32, ...utils.WithWriterArgs) error) *MockWriteBufferPlcValueBased_WriteFloat32_Call {
	_c.Call.Return(run)
	return _c
}

// WriteFloat64 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferPlcValueBased) WriteFloat64(logicalName string, bitLength uint8, value float64, writerArgs ...utils.WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint8, float64, ...utils.WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferPlcValueBased_WriteFloat64_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteFloat64'
type MockWriteBufferPlcValueBased_WriteFloat64_Call struct {
	*mock.Call
}

// WriteFloat64 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - value float64
//   - writerArgs ...utils.WithWriterArgs
func (_e *MockWriteBufferPlcValueBased_Expecter) WriteFloat64(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferPlcValueBased_WriteFloat64_Call {
	return &MockWriteBufferPlcValueBased_WriteFloat64_Call{Call: _e.mock.On("WriteFloat64",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferPlcValueBased_WriteFloat64_Call) Run(run func(logicalName string, bitLength uint8, value float64, writerArgs ...utils.WithWriterArgs)) *MockWriteBufferPlcValueBased_WriteFloat64_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]utils.WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(utils.WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint8), args[2].(float64), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteFloat64_Call) Return(_a0 error) *MockWriteBufferPlcValueBased_WriteFloat64_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteFloat64_Call) RunAndReturn(run func(string, uint8, float64, ...utils.WithWriterArgs) error) *MockWriteBufferPlcValueBased_WriteFloat64_Call {
	_c.Call.Return(run)
	return _c
}

// WriteInt16 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferPlcValueBased) WriteInt16(logicalName string, bitLength uint8, value int16, writerArgs ...utils.WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint8, int16, ...utils.WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferPlcValueBased_WriteInt16_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteInt16'
type MockWriteBufferPlcValueBased_WriteInt16_Call struct {
	*mock.Call
}

// WriteInt16 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - value int16
//   - writerArgs ...utils.WithWriterArgs
func (_e *MockWriteBufferPlcValueBased_Expecter) WriteInt16(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferPlcValueBased_WriteInt16_Call {
	return &MockWriteBufferPlcValueBased_WriteInt16_Call{Call: _e.mock.On("WriteInt16",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferPlcValueBased_WriteInt16_Call) Run(run func(logicalName string, bitLength uint8, value int16, writerArgs ...utils.WithWriterArgs)) *MockWriteBufferPlcValueBased_WriteInt16_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]utils.WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(utils.WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint8), args[2].(int16), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteInt16_Call) Return(_a0 error) *MockWriteBufferPlcValueBased_WriteInt16_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteInt16_Call) RunAndReturn(run func(string, uint8, int16, ...utils.WithWriterArgs) error) *MockWriteBufferPlcValueBased_WriteInt16_Call {
	_c.Call.Return(run)
	return _c
}

// WriteInt32 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferPlcValueBased) WriteInt32(logicalName string, bitLength uint8, value int32, writerArgs ...utils.WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint8, int32, ...utils.WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferPlcValueBased_WriteInt32_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteInt32'
type MockWriteBufferPlcValueBased_WriteInt32_Call struct {
	*mock.Call
}

// WriteInt32 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - value int32
//   - writerArgs ...utils.WithWriterArgs
func (_e *MockWriteBufferPlcValueBased_Expecter) WriteInt32(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferPlcValueBased_WriteInt32_Call {
	return &MockWriteBufferPlcValueBased_WriteInt32_Call{Call: _e.mock.On("WriteInt32",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferPlcValueBased_WriteInt32_Call) Run(run func(logicalName string, bitLength uint8, value int32, writerArgs ...utils.WithWriterArgs)) *MockWriteBufferPlcValueBased_WriteInt32_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]utils.WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(utils.WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint8), args[2].(int32), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteInt32_Call) Return(_a0 error) *MockWriteBufferPlcValueBased_WriteInt32_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteInt32_Call) RunAndReturn(run func(string, uint8, int32, ...utils.WithWriterArgs) error) *MockWriteBufferPlcValueBased_WriteInt32_Call {
	_c.Call.Return(run)
	return _c
}

// WriteInt64 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferPlcValueBased) WriteInt64(logicalName string, bitLength uint8, value int64, writerArgs ...utils.WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint8, int64, ...utils.WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferPlcValueBased_WriteInt64_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteInt64'
type MockWriteBufferPlcValueBased_WriteInt64_Call struct {
	*mock.Call
}

// WriteInt64 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - value int64
//   - writerArgs ...utils.WithWriterArgs
func (_e *MockWriteBufferPlcValueBased_Expecter) WriteInt64(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferPlcValueBased_WriteInt64_Call {
	return &MockWriteBufferPlcValueBased_WriteInt64_Call{Call: _e.mock.On("WriteInt64",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferPlcValueBased_WriteInt64_Call) Run(run func(logicalName string, bitLength uint8, value int64, writerArgs ...utils.WithWriterArgs)) *MockWriteBufferPlcValueBased_WriteInt64_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]utils.WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(utils.WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint8), args[2].(int64), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteInt64_Call) Return(_a0 error) *MockWriteBufferPlcValueBased_WriteInt64_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteInt64_Call) RunAndReturn(run func(string, uint8, int64, ...utils.WithWriterArgs) error) *MockWriteBufferPlcValueBased_WriteInt64_Call {
	_c.Call.Return(run)
	return _c
}

// WriteInt8 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferPlcValueBased) WriteInt8(logicalName string, bitLength uint8, value int8, writerArgs ...utils.WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint8, int8, ...utils.WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferPlcValueBased_WriteInt8_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteInt8'
type MockWriteBufferPlcValueBased_WriteInt8_Call struct {
	*mock.Call
}

// WriteInt8 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - value int8
//   - writerArgs ...utils.WithWriterArgs
func (_e *MockWriteBufferPlcValueBased_Expecter) WriteInt8(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferPlcValueBased_WriteInt8_Call {
	return &MockWriteBufferPlcValueBased_WriteInt8_Call{Call: _e.mock.On("WriteInt8",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferPlcValueBased_WriteInt8_Call) Run(run func(logicalName string, bitLength uint8, value int8, writerArgs ...utils.WithWriterArgs)) *MockWriteBufferPlcValueBased_WriteInt8_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]utils.WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(utils.WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint8), args[2].(int8), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteInt8_Call) Return(_a0 error) *MockWriteBufferPlcValueBased_WriteInt8_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteInt8_Call) RunAndReturn(run func(string, uint8, int8, ...utils.WithWriterArgs) error) *MockWriteBufferPlcValueBased_WriteInt8_Call {
	_c.Call.Return(run)
	return _c
}

// WriteSerializable provides a mock function with given fields: ctx, serializable
func (_m *MockWriteBufferPlcValueBased) WriteSerializable(ctx context.Context, serializable utils.Serializable) error {
	ret := _m.Called(ctx, serializable)

	var r0 error
	if rf, ok := ret.Get(0).(func(context.Context, utils.Serializable) error); ok {
		r0 = rf(ctx, serializable)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferPlcValueBased_WriteSerializable_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteSerializable'
type MockWriteBufferPlcValueBased_WriteSerializable_Call struct {
	*mock.Call
}

// WriteSerializable is a helper method to define mock.On call
//   - ctx context.Context
//   - serializable utils.Serializable
func (_e *MockWriteBufferPlcValueBased_Expecter) WriteSerializable(ctx interface{}, serializable interface{}) *MockWriteBufferPlcValueBased_WriteSerializable_Call {
	return &MockWriteBufferPlcValueBased_WriteSerializable_Call{Call: _e.mock.On("WriteSerializable", ctx, serializable)}
}

func (_c *MockWriteBufferPlcValueBased_WriteSerializable_Call) Run(run func(ctx context.Context, serializable utils.Serializable)) *MockWriteBufferPlcValueBased_WriteSerializable_Call {
	_c.Call.Run(func(args mock.Arguments) {
		run(args[0].(context.Context), args[1].(utils.Serializable))
	})
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteSerializable_Call) Return(_a0 error) *MockWriteBufferPlcValueBased_WriteSerializable_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteSerializable_Call) RunAndReturn(run func(context.Context, utils.Serializable) error) *MockWriteBufferPlcValueBased_WriteSerializable_Call {
	_c.Call.Return(run)
	return _c
}

// WriteString provides a mock function with given fields: logicalName, bitLength, encoding, value, writerArgs
func (_m *MockWriteBufferPlcValueBased) WriteString(logicalName string, bitLength uint32, encoding string, value string, writerArgs ...utils.WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, encoding, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint32, string, string, ...utils.WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, encoding, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferPlcValueBased_WriteString_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteString'
type MockWriteBufferPlcValueBased_WriteString_Call struct {
	*mock.Call
}

// WriteString is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint32
//   - encoding string
//   - value string
//   - writerArgs ...utils.WithWriterArgs
func (_e *MockWriteBufferPlcValueBased_Expecter) WriteString(logicalName interface{}, bitLength interface{}, encoding interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferPlcValueBased_WriteString_Call {
	return &MockWriteBufferPlcValueBased_WriteString_Call{Call: _e.mock.On("WriteString",
		append([]interface{}{logicalName, bitLength, encoding, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferPlcValueBased_WriteString_Call) Run(run func(logicalName string, bitLength uint32, encoding string, value string, writerArgs ...utils.WithWriterArgs)) *MockWriteBufferPlcValueBased_WriteString_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]utils.WithWriterArgs, len(args)-4)
		for i, a := range args[4:] {
			if a != nil {
				variadicArgs[i] = a.(utils.WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint32), args[2].(string), args[3].(string), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteString_Call) Return(_a0 error) *MockWriteBufferPlcValueBased_WriteString_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteString_Call) RunAndReturn(run func(string, uint32, string, string, ...utils.WithWriterArgs) error) *MockWriteBufferPlcValueBased_WriteString_Call {
	_c.Call.Return(run)
	return _c
}

// WriteUint16 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferPlcValueBased) WriteUint16(logicalName string, bitLength uint8, value uint16, writerArgs ...utils.WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint8, uint16, ...utils.WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferPlcValueBased_WriteUint16_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteUint16'
type MockWriteBufferPlcValueBased_WriteUint16_Call struct {
	*mock.Call
}

// WriteUint16 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - value uint16
//   - writerArgs ...utils.WithWriterArgs
func (_e *MockWriteBufferPlcValueBased_Expecter) WriteUint16(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferPlcValueBased_WriteUint16_Call {
	return &MockWriteBufferPlcValueBased_WriteUint16_Call{Call: _e.mock.On("WriteUint16",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferPlcValueBased_WriteUint16_Call) Run(run func(logicalName string, bitLength uint8, value uint16, writerArgs ...utils.WithWriterArgs)) *MockWriteBufferPlcValueBased_WriteUint16_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]utils.WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(utils.WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint8), args[2].(uint16), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteUint16_Call) Return(_a0 error) *MockWriteBufferPlcValueBased_WriteUint16_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteUint16_Call) RunAndReturn(run func(string, uint8, uint16, ...utils.WithWriterArgs) error) *MockWriteBufferPlcValueBased_WriteUint16_Call {
	_c.Call.Return(run)
	return _c
}

// WriteUint32 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferPlcValueBased) WriteUint32(logicalName string, bitLength uint8, value uint32, writerArgs ...utils.WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint8, uint32, ...utils.WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferPlcValueBased_WriteUint32_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteUint32'
type MockWriteBufferPlcValueBased_WriteUint32_Call struct {
	*mock.Call
}

// WriteUint32 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - value uint32
//   - writerArgs ...utils.WithWriterArgs
func (_e *MockWriteBufferPlcValueBased_Expecter) WriteUint32(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferPlcValueBased_WriteUint32_Call {
	return &MockWriteBufferPlcValueBased_WriteUint32_Call{Call: _e.mock.On("WriteUint32",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferPlcValueBased_WriteUint32_Call) Run(run func(logicalName string, bitLength uint8, value uint32, writerArgs ...utils.WithWriterArgs)) *MockWriteBufferPlcValueBased_WriteUint32_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]utils.WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(utils.WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint8), args[2].(uint32), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteUint32_Call) Return(_a0 error) *MockWriteBufferPlcValueBased_WriteUint32_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteUint32_Call) RunAndReturn(run func(string, uint8, uint32, ...utils.WithWriterArgs) error) *MockWriteBufferPlcValueBased_WriteUint32_Call {
	_c.Call.Return(run)
	return _c
}

// WriteUint64 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferPlcValueBased) WriteUint64(logicalName string, bitLength uint8, value uint64, writerArgs ...utils.WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint8, uint64, ...utils.WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferPlcValueBased_WriteUint64_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteUint64'
type MockWriteBufferPlcValueBased_WriteUint64_Call struct {
	*mock.Call
}

// WriteUint64 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - value uint64
//   - writerArgs ...utils.WithWriterArgs
func (_e *MockWriteBufferPlcValueBased_Expecter) WriteUint64(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferPlcValueBased_WriteUint64_Call {
	return &MockWriteBufferPlcValueBased_WriteUint64_Call{Call: _e.mock.On("WriteUint64",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferPlcValueBased_WriteUint64_Call) Run(run func(logicalName string, bitLength uint8, value uint64, writerArgs ...utils.WithWriterArgs)) *MockWriteBufferPlcValueBased_WriteUint64_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]utils.WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(utils.WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint8), args[2].(uint64), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteUint64_Call) Return(_a0 error) *MockWriteBufferPlcValueBased_WriteUint64_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteUint64_Call) RunAndReturn(run func(string, uint8, uint64, ...utils.WithWriterArgs) error) *MockWriteBufferPlcValueBased_WriteUint64_Call {
	_c.Call.Return(run)
	return _c
}

// WriteUint8 provides a mock function with given fields: logicalName, bitLength, value, writerArgs
func (_m *MockWriteBufferPlcValueBased) WriteUint8(logicalName string, bitLength uint8, value uint8, writerArgs ...utils.WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, logicalName, bitLength, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(string, uint8, uint8, ...utils.WithWriterArgs) error); ok {
		r0 = rf(logicalName, bitLength, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferPlcValueBased_WriteUint8_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteUint8'
type MockWriteBufferPlcValueBased_WriteUint8_Call struct {
	*mock.Call
}

// WriteUint8 is a helper method to define mock.On call
//   - logicalName string
//   - bitLength uint8
//   - value uint8
//   - writerArgs ...utils.WithWriterArgs
func (_e *MockWriteBufferPlcValueBased_Expecter) WriteUint8(logicalName interface{}, bitLength interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferPlcValueBased_WriteUint8_Call {
	return &MockWriteBufferPlcValueBased_WriteUint8_Call{Call: _e.mock.On("WriteUint8",
		append([]interface{}{logicalName, bitLength, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferPlcValueBased_WriteUint8_Call) Run(run func(logicalName string, bitLength uint8, value uint8, writerArgs ...utils.WithWriterArgs)) *MockWriteBufferPlcValueBased_WriteUint8_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]utils.WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(utils.WithWriterArgs)
			}
		}
		run(args[0].(string), args[1].(uint8), args[2].(uint8), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteUint8_Call) Return(_a0 error) *MockWriteBufferPlcValueBased_WriteUint8_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteUint8_Call) RunAndReturn(run func(string, uint8, uint8, ...utils.WithWriterArgs) error) *MockWriteBufferPlcValueBased_WriteUint8_Call {
	_c.Call.Return(run)
	return _c
}

// WriteVirtual provides a mock function with given fields: ctx, logicalName, value, writerArgs
func (_m *MockWriteBufferPlcValueBased) WriteVirtual(ctx context.Context, logicalName string, value interface{}, writerArgs ...utils.WithWriterArgs) error {
	_va := make([]interface{}, len(writerArgs))
	for _i := range writerArgs {
		_va[_i] = writerArgs[_i]
	}
	var _ca []interface{}
	_ca = append(_ca, ctx, logicalName, value)
	_ca = append(_ca, _va...)
	ret := _m.Called(_ca...)

	var r0 error
	if rf, ok := ret.Get(0).(func(context.Context, string, interface{}, ...utils.WithWriterArgs) error); ok {
		r0 = rf(ctx, logicalName, value, writerArgs...)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// MockWriteBufferPlcValueBased_WriteVirtual_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteVirtual'
type MockWriteBufferPlcValueBased_WriteVirtual_Call struct {
	*mock.Call
}

// WriteVirtual is a helper method to define mock.On call
//   - ctx context.Context
//   - logicalName string
//   - value interface{}
//   - writerArgs ...utils.WithWriterArgs
func (_e *MockWriteBufferPlcValueBased_Expecter) WriteVirtual(ctx interface{}, logicalName interface{}, value interface{}, writerArgs ...interface{}) *MockWriteBufferPlcValueBased_WriteVirtual_Call {
	return &MockWriteBufferPlcValueBased_WriteVirtual_Call{Call: _e.mock.On("WriteVirtual",
		append([]interface{}{ctx, logicalName, value}, writerArgs...)...)}
}

func (_c *MockWriteBufferPlcValueBased_WriteVirtual_Call) Run(run func(ctx context.Context, logicalName string, value interface{}, writerArgs ...utils.WithWriterArgs)) *MockWriteBufferPlcValueBased_WriteVirtual_Call {
	_c.Call.Run(func(args mock.Arguments) {
		variadicArgs := make([]utils.WithWriterArgs, len(args)-3)
		for i, a := range args[3:] {
			if a != nil {
				variadicArgs[i] = a.(utils.WithWriterArgs)
			}
		}
		run(args[0].(context.Context), args[1].(string), args[2].(interface{}), variadicArgs...)
	})
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteVirtual_Call) Return(_a0 error) *MockWriteBufferPlcValueBased_WriteVirtual_Call {
	_c.Call.Return(_a0)
	return _c
}

func (_c *MockWriteBufferPlcValueBased_WriteVirtual_Call) RunAndReturn(run func(context.Context, string, interface{}, ...utils.WithWriterArgs) error) *MockWriteBufferPlcValueBased_WriteVirtual_Call {
	_c.Call.Return(run)
	return _c
}

type mockConstructorTestingTNewMockWriteBufferPlcValueBased interface {
	mock.TestingT
	Cleanup(func())
}

// NewMockWriteBufferPlcValueBased creates a new instance of MockWriteBufferPlcValueBased. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
func NewMockWriteBufferPlcValueBased(t mockConstructorTestingTNewMockWriteBufferPlcValueBased) *MockWriteBufferPlcValueBased {
	mock := &MockWriteBufferPlcValueBased{}
	mock.Mock.Test(t)

	t.Cleanup(func() { mock.AssertExpectations(t) })

	return mock
}
