/*
 * 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 "plc4xGenerator -type=ConnectionMetadata"; DO NOT EDIT.

package knxnetip

import (
	"context"
	"encoding/binary"
	"fmt"
	"github.com/apache/plc4x/plc4go/spi/utils"
)

var _ = fmt.Printf

func (d *ConnectionMetadata) Serialize() ([]byte, error) {
	if d == nil {
		return nil, fmt.Errorf("(*DeviceInfoCache)(nil)")
	}
	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian))
	if err := d.SerializeWithWriteBuffer(context.Background(), wb); err != nil {
		return nil, err
	}
	return wb.GetBytes(), nil
}

func (d *ConnectionMetadata) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
	if d == nil {
		return fmt.Errorf("(*DeviceInfoCache)(nil)")
	}
	if err := writeBuffer.PushContext("ConnectionMetadata"); err != nil {
		return err
	}

	if err := writeBuffer.WriteString("knxMedium", uint32(len(d.KnxMedium.String())*8), d.KnxMedium.String()); err != nil {
		return err
	}

	if err := writeBuffer.WriteString("gatewayName", uint32(len(d.GatewayName)*8), d.GatewayName); err != nil {
		return err
	}

	if err := writeBuffer.WriteString("gatewayKnxAddress", uint32(len(d.GatewayKnxAddress)*8), d.GatewayKnxAddress); err != nil {
		return err
	}

	if err := writeBuffer.WriteString("clientKnxAddress", uint32(len(d.ClientKnxAddress)*8), d.ClientKnxAddress); err != nil {
		return err
	}
	{
		_value := fmt.Sprintf("%v", d.ProjectNumber)

		if err := writeBuffer.WriteString("projectNumber", uint32(len(_value)*8), _value); err != nil {
			return err
		}
	}
	{
		_value := fmt.Sprintf("%v", d.InstallationNumber)

		if err := writeBuffer.WriteString("installationNumber", uint32(len(_value)*8), _value); err != nil {
			return err
		}
	}
	if err := writeBuffer.WriteByteArray("deviceSerialNumber", d.DeviceSerialNumber); err != nil {
		return err
	}
	if err := writeBuffer.WriteByteArray("deviceMulticastAddress", d.DeviceMulticastAddress); err != nil {
		return err
	}
	if err := writeBuffer.WriteByteArray("deviceMacAddress", d.DeviceMacAddress); err != nil {
		return err
	}
	if err := writeBuffer.PushContext("supportedServices", utils.WithRenderAsList(true)); err != nil {
		return err
	}
	for _, elem := range d.SupportedServices {
		if err := writeBuffer.WriteString("", uint32(len(elem)*8), elem); err != nil {
			return err
		}
	}
	if err := writeBuffer.PopContext("supportedServices", utils.WithRenderAsList(true)); err != nil {
		return err
	}
	if err := writeBuffer.PopContext("ConnectionMetadata"); err != nil {
		return err
	}
	return nil
}

func (d *ConnectionMetadata) String() string {
	if alternateStringer, ok := any(d).(utils.AlternateStringer); ok {
		if alternateString, use := alternateStringer.AlternateString(); use {
			return alternateString
		}
	}
	wb := utils.NewWriteBufferBoxBased(utils.WithWriteBufferBoxBasedMergeSingleBoxes(), utils.WithWriteBufferBoxBasedOmitEmptyBoxes())
	if err := wb.WriteSerializable(context.Background(), d); err != nil {
		return err.Error()
	}
	return wb.GetBox().String()
}
