// Copyright © 2023 Cisco Systems, Inc. and its affiliates.
// All rights reserved.
//
// Licensed under the Mozilla Public 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://mozilla.org/MPL/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.
//
// SPDX-License-Identifier: MPL-2.0

// Code generated by "gen/generator.go"; DO NOT EDIT.

package provider

// Section below is generated&owned by "gen/generator.go". //template:begin imports
import (
	"context"
	"fmt"
	"reflect"
	"regexp"
	"strconv"
	"strings"

	"github.com/CiscoDevNet/terraform-provider-iosxe/internal/provider/helpers"
	"github.com/hashicorp/terraform-plugin-framework/types"
	"github.com/tidwall/gjson"
	"github.com/tidwall/sjson"
)

// End of section. //template:end imports

// Section below is generated&owned by "gen/generator.go". //template:begin types
type MSDP struct {
	Device       types.String    `tfsdk:"device"`
	Id           types.String    `tfsdk:"id"`
	DeleteMode   types.String    `tfsdk:"delete_mode"`
	OriginatorId types.String    `tfsdk:"originator_id"`
	Peers        []MSDPPeers     `tfsdk:"peers"`
	Passwords    []MSDPPasswords `tfsdk:"passwords"`
	Vrfs         []MSDPVrfs      `tfsdk:"vrfs"`
}

type MSDPData struct {
	Device       types.String    `tfsdk:"device"`
	Id           types.String    `tfsdk:"id"`
	OriginatorId types.String    `tfsdk:"originator_id"`
	Peers        []MSDPPeers     `tfsdk:"peers"`
	Passwords    []MSDPPasswords `tfsdk:"passwords"`
	Vrfs         []MSDPVrfs      `tfsdk:"vrfs"`
}
type MSDPPeers struct {
	Addr                  types.String `tfsdk:"addr"`
	RemoteAs              types.Int64  `tfsdk:"remote_as"`
	ConnectSourceLoopback types.Int64  `tfsdk:"connect_source_loopback"`
}
type MSDPPasswords struct {
	Addr       types.String `tfsdk:"addr"`
	Encryption types.Int64  `tfsdk:"encryption"`
	Password   types.String `tfsdk:"password"`
}
type MSDPVrfs struct {
	Vrf          types.String        `tfsdk:"vrf"`
	OriginatorId types.String        `tfsdk:"originator_id"`
	Peers        []MSDPVrfsPeers     `tfsdk:"peers"`
	Passwords    []MSDPVrfsPasswords `tfsdk:"passwords"`
}
type MSDPVrfsPeers struct {
	Addr                  types.String `tfsdk:"addr"`
	RemoteAs              types.Int64  `tfsdk:"remote_as"`
	ConnectSourceLoopback types.Int64  `tfsdk:"connect_source_loopback"`
}
type MSDPVrfsPasswords struct {
	Addr       types.String `tfsdk:"addr"`
	Encryption types.Int64  `tfsdk:"encryption"`
	Password   types.String `tfsdk:"password"`
}

// End of section. //template:end types

// Section below is generated&owned by "gen/generator.go". //template:begin getPath

func (data MSDP) getPath() string {
	return "Cisco-IOS-XE-native:native/ip/Cisco-IOS-XE-multicast:msdp"
}

func (data MSDPData) getPath() string {
	return "Cisco-IOS-XE-native:native/ip/Cisco-IOS-XE-multicast:msdp"
}

// if last path element has a key -> remove it
func (data MSDP) getPathShort() string {
	path := data.getPath()
	re := regexp.MustCompile(`(.*)=[^\/]*$`)
	matches := re.FindStringSubmatch(path)
	if len(matches) <= 1 {
		return path
	}
	return matches[1]
}

// End of section. //template:end getPath

// Section below is generated&owned by "gen/generator.go". //template:begin toBody

func (data MSDP) toBody(ctx context.Context) string {
	body := `{"` + helpers.LastElement(data.getPath()) + `":{}}`
	if !data.OriginatorId.IsNull() && !data.OriginatorId.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"originator-id", data.OriginatorId.ValueString())
	}
	if len(data.Peers) > 0 {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"peer", []interface{}{})
		for index, item := range data.Peers {
			if !item.Addr.IsNull() && !item.Addr.IsUnknown() {
				body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"peer"+"."+strconv.Itoa(index)+"."+"addr", item.Addr.ValueString())
			}
			if !item.RemoteAs.IsNull() && !item.RemoteAs.IsUnknown() {
				body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"peer"+"."+strconv.Itoa(index)+"."+"remote-as", strconv.FormatInt(item.RemoteAs.ValueInt64(), 10))
			}
			if !item.ConnectSourceLoopback.IsNull() && !item.ConnectSourceLoopback.IsUnknown() {
				body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"peer"+"."+strconv.Itoa(index)+"."+"connect-source.Loopback", strconv.FormatInt(item.ConnectSourceLoopback.ValueInt64(), 10))
			}
		}
	}
	if len(data.Passwords) > 0 {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"password.peer-list", []interface{}{})
		for index, item := range data.Passwords {
			if !item.Addr.IsNull() && !item.Addr.IsUnknown() {
				body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"password.peer-list"+"."+strconv.Itoa(index)+"."+"addr", item.Addr.ValueString())
			}
			if !item.Encryption.IsNull() && !item.Encryption.IsUnknown() {
				body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"password.peer-list"+"."+strconv.Itoa(index)+"."+"encryption", strconv.FormatInt(item.Encryption.ValueInt64(), 10))
			}
			if !item.Password.IsNull() && !item.Password.IsUnknown() {
				body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"password.peer-list"+"."+strconv.Itoa(index)+"."+"password", item.Password.ValueString())
			}
		}
	}
	if len(data.Vrfs) > 0 {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"vrf", []interface{}{})
		for index, item := range data.Vrfs {
			if !item.Vrf.IsNull() && !item.Vrf.IsUnknown() {
				body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"vrf"+"."+strconv.Itoa(index)+"."+"name", item.Vrf.ValueString())
			}
			if !item.OriginatorId.IsNull() && !item.OriginatorId.IsUnknown() {
				body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"vrf"+"."+strconv.Itoa(index)+"."+"originator-id", item.OriginatorId.ValueString())
			}
			if len(item.Peers) > 0 {
				body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"vrf"+"."+strconv.Itoa(index)+"."+"peer", []interface{}{})
				for cindex, citem := range item.Peers {
					if !citem.Addr.IsNull() && !citem.Addr.IsUnknown() {
						body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"vrf"+"."+strconv.Itoa(index)+"."+"peer"+"."+strconv.Itoa(cindex)+"."+"addr", citem.Addr.ValueString())
					}
					if !citem.RemoteAs.IsNull() && !citem.RemoteAs.IsUnknown() {
						body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"vrf"+"."+strconv.Itoa(index)+"."+"peer"+"."+strconv.Itoa(cindex)+"."+"remote-as", strconv.FormatInt(citem.RemoteAs.ValueInt64(), 10))
					}
					if !citem.ConnectSourceLoopback.IsNull() && !citem.ConnectSourceLoopback.IsUnknown() {
						body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"vrf"+"."+strconv.Itoa(index)+"."+"peer"+"."+strconv.Itoa(cindex)+"."+"connect-source.Loopback", strconv.FormatInt(citem.ConnectSourceLoopback.ValueInt64(), 10))
					}
				}
			}
			if len(item.Passwords) > 0 {
				body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"vrf"+"."+strconv.Itoa(index)+"."+"password.peer-list", []interface{}{})
				for cindex, citem := range item.Passwords {
					if !citem.Addr.IsNull() && !citem.Addr.IsUnknown() {
						body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"vrf"+"."+strconv.Itoa(index)+"."+"password.peer-list"+"."+strconv.Itoa(cindex)+"."+"addr", citem.Addr.ValueString())
					}
					if !citem.Encryption.IsNull() && !citem.Encryption.IsUnknown() {
						body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"vrf"+"."+strconv.Itoa(index)+"."+"password.peer-list"+"."+strconv.Itoa(cindex)+"."+"encryption", strconv.FormatInt(citem.Encryption.ValueInt64(), 10))
					}
					if !citem.Password.IsNull() && !citem.Password.IsUnknown() {
						body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"vrf"+"."+strconv.Itoa(index)+"."+"password.peer-list"+"."+strconv.Itoa(cindex)+"."+"password", citem.Password.ValueString())
					}
				}
			}
		}
	}
	return body
}

// End of section. //template:end toBody

// Section below is generated&owned by "gen/generator.go". //template:begin updateFromBody

func (data *MSDP) updateFromBody(ctx context.Context, res gjson.Result) {
	prefix := helpers.LastElement(data.getPath()) + "."
	if res.Get(helpers.LastElement(data.getPath())).IsArray() {
		prefix += "0."
	}
	if value := res.Get(prefix + "originator-id"); value.Exists() && !data.OriginatorId.IsNull() {
		data.OriginatorId = types.StringValue(value.String())
	} else {
		data.OriginatorId = types.StringNull()
	}
	for i := range data.Peers {
		keys := [...]string{"addr"}
		keyValues := [...]string{data.Peers[i].Addr.ValueString()}

		var r gjson.Result
		res.Get(prefix + "peer").ForEach(
			func(_, v gjson.Result) bool {
				found := false
				for ik := range keys {
					if v.Get(keys[ik]).String() == keyValues[ik] {
						found = true
						continue
					}
					found = false
					break
				}
				if found {
					r = v
					return false
				}
				return true
			},
		)
		if value := r.Get("addr"); value.Exists() && !data.Peers[i].Addr.IsNull() {
			data.Peers[i].Addr = types.StringValue(value.String())
		} else {
			data.Peers[i].Addr = types.StringNull()
		}
		if value := r.Get("remote-as"); value.Exists() && !data.Peers[i].RemoteAs.IsNull() {
			data.Peers[i].RemoteAs = types.Int64Value(value.Int())
		} else {
			data.Peers[i].RemoteAs = types.Int64Null()
		}
		if value := r.Get("connect-source.Loopback"); value.Exists() && !data.Peers[i].ConnectSourceLoopback.IsNull() {
			data.Peers[i].ConnectSourceLoopback = types.Int64Value(value.Int())
		} else {
			data.Peers[i].ConnectSourceLoopback = types.Int64Null()
		}
	}
	for i := range data.Passwords {
		keys := [...]string{"addr"}
		keyValues := [...]string{data.Passwords[i].Addr.ValueString()}

		var r gjson.Result
		res.Get(prefix + "password.peer-list").ForEach(
			func(_, v gjson.Result) bool {
				found := false
				for ik := range keys {
					if v.Get(keys[ik]).String() == keyValues[ik] {
						found = true
						continue
					}
					found = false
					break
				}
				if found {
					r = v
					return false
				}
				return true
			},
		)
		if value := r.Get("addr"); value.Exists() && !data.Passwords[i].Addr.IsNull() {
			data.Passwords[i].Addr = types.StringValue(value.String())
		} else {
			data.Passwords[i].Addr = types.StringNull()
		}
	}
	for i := range data.Vrfs {
		keys := [...]string{"name"}
		keyValues := [...]string{data.Vrfs[i].Vrf.ValueString()}

		var r gjson.Result
		res.Get(prefix + "vrf").ForEach(
			func(_, v gjson.Result) bool {
				found := false
				for ik := range keys {
					if v.Get(keys[ik]).String() == keyValues[ik] {
						found = true
						continue
					}
					found = false
					break
				}
				if found {
					r = v
					return false
				}
				return true
			},
		)
		if value := r.Get("name"); value.Exists() && !data.Vrfs[i].Vrf.IsNull() {
			data.Vrfs[i].Vrf = types.StringValue(value.String())
		} else {
			data.Vrfs[i].Vrf = types.StringNull()
		}
		if value := r.Get("originator-id"); value.Exists() && !data.Vrfs[i].OriginatorId.IsNull() {
			data.Vrfs[i].OriginatorId = types.StringValue(value.String())
		} else {
			data.Vrfs[i].OriginatorId = types.StringNull()
		}
		for ci := range data.Vrfs[i].Peers {
			keys := [...]string{"addr"}
			keyValues := [...]string{data.Vrfs[i].Peers[ci].Addr.ValueString()}

			var cr gjson.Result
			r.Get("peer").ForEach(
				func(_, v gjson.Result) bool {
					found := false
					for ik := range keys {
						if v.Get(keys[ik]).String() == keyValues[ik] {
							found = true
							continue
						}
						found = false
						break
					}
					if found {
						cr = v
						return false
					}
					return true
				},
			)
			if value := cr.Get("addr"); value.Exists() && !data.Vrfs[i].Peers[ci].Addr.IsNull() {
				data.Vrfs[i].Peers[ci].Addr = types.StringValue(value.String())
			} else {
				data.Vrfs[i].Peers[ci].Addr = types.StringNull()
			}
			if value := cr.Get("remote-as"); value.Exists() && !data.Vrfs[i].Peers[ci].RemoteAs.IsNull() {
				data.Vrfs[i].Peers[ci].RemoteAs = types.Int64Value(value.Int())
			} else {
				data.Vrfs[i].Peers[ci].RemoteAs = types.Int64Null()
			}
			if value := cr.Get("connect-source.Loopback"); value.Exists() && !data.Vrfs[i].Peers[ci].ConnectSourceLoopback.IsNull() {
				data.Vrfs[i].Peers[ci].ConnectSourceLoopback = types.Int64Value(value.Int())
			} else {
				data.Vrfs[i].Peers[ci].ConnectSourceLoopback = types.Int64Null()
			}
		}
		for ci := range data.Vrfs[i].Passwords {
			keys := [...]string{"addr"}
			keyValues := [...]string{data.Vrfs[i].Passwords[ci].Addr.ValueString()}

			var cr gjson.Result
			r.Get("password.peer-list").ForEach(
				func(_, v gjson.Result) bool {
					found := false
					for ik := range keys {
						if v.Get(keys[ik]).String() == keyValues[ik] {
							found = true
							continue
						}
						found = false
						break
					}
					if found {
						cr = v
						return false
					}
					return true
				},
			)
			if value := cr.Get("addr"); value.Exists() && !data.Vrfs[i].Passwords[ci].Addr.IsNull() {
				data.Vrfs[i].Passwords[ci].Addr = types.StringValue(value.String())
			} else {
				data.Vrfs[i].Passwords[ci].Addr = types.StringNull()
			}
		}
	}
}

// End of section. //template:end updateFromBody

// Section below is generated&owned by "gen/generator.go". //template:begin fromBody

func (data *MSDP) fromBody(ctx context.Context, res gjson.Result) {
	prefix := helpers.LastElement(data.getPath()) + "."
	if res.Get(helpers.LastElement(data.getPath())).IsArray() {
		prefix += "0."
	}
	if value := res.Get(prefix + "originator-id"); value.Exists() {
		data.OriginatorId = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "peer"); value.Exists() {
		data.Peers = make([]MSDPPeers, 0)
		value.ForEach(func(k, v gjson.Result) bool {
			item := MSDPPeers{}
			if cValue := v.Get("addr"); cValue.Exists() {
				item.Addr = types.StringValue(cValue.String())
			}
			if cValue := v.Get("remote-as"); cValue.Exists() {
				item.RemoteAs = types.Int64Value(cValue.Int())
			}
			if cValue := v.Get("connect-source.Loopback"); cValue.Exists() {
				item.ConnectSourceLoopback = types.Int64Value(cValue.Int())
			}
			data.Peers = append(data.Peers, item)
			return true
		})
	}
	if value := res.Get(prefix + "password.peer-list"); value.Exists() {
		data.Passwords = make([]MSDPPasswords, 0)
		value.ForEach(func(k, v gjson.Result) bool {
			item := MSDPPasswords{}
			if cValue := v.Get("addr"); cValue.Exists() {
				item.Addr = types.StringValue(cValue.String())
			}
			if cValue := v.Get("encryption"); cValue.Exists() {
				item.Encryption = types.Int64Value(cValue.Int())
			}
			if cValue := v.Get("password"); cValue.Exists() {
				item.Password = types.StringValue(cValue.String())
			}
			data.Passwords = append(data.Passwords, item)
			return true
		})
	}
	if value := res.Get(prefix + "vrf"); value.Exists() {
		data.Vrfs = make([]MSDPVrfs, 0)
		value.ForEach(func(k, v gjson.Result) bool {
			item := MSDPVrfs{}
			if cValue := v.Get("name"); cValue.Exists() {
				item.Vrf = types.StringValue(cValue.String())
			}
			if cValue := v.Get("originator-id"); cValue.Exists() {
				item.OriginatorId = types.StringValue(cValue.String())
			}
			if cValue := v.Get("peer"); cValue.Exists() {
				item.Peers = make([]MSDPVrfsPeers, 0)
				cValue.ForEach(func(ck, cv gjson.Result) bool {
					cItem := MSDPVrfsPeers{}
					if ccValue := cv.Get("addr"); ccValue.Exists() {
						cItem.Addr = types.StringValue(ccValue.String())
					}
					if ccValue := cv.Get("remote-as"); ccValue.Exists() {
						cItem.RemoteAs = types.Int64Value(ccValue.Int())
					}
					if ccValue := cv.Get("connect-source.Loopback"); ccValue.Exists() {
						cItem.ConnectSourceLoopback = types.Int64Value(ccValue.Int())
					}
					item.Peers = append(item.Peers, cItem)
					return true
				})
			}
			if cValue := v.Get("password.peer-list"); cValue.Exists() {
				item.Passwords = make([]MSDPVrfsPasswords, 0)
				cValue.ForEach(func(ck, cv gjson.Result) bool {
					cItem := MSDPVrfsPasswords{}
					if ccValue := cv.Get("addr"); ccValue.Exists() {
						cItem.Addr = types.StringValue(ccValue.String())
					}
					if ccValue := cv.Get("encryption"); ccValue.Exists() {
						cItem.Encryption = types.Int64Value(ccValue.Int())
					}
					if ccValue := cv.Get("password"); ccValue.Exists() {
						cItem.Password = types.StringValue(ccValue.String())
					}
					item.Passwords = append(item.Passwords, cItem)
					return true
				})
			}
			data.Vrfs = append(data.Vrfs, item)
			return true
		})
	}
}

// End of section. //template:end fromBody

// Section below is generated&owned by "gen/generator.go". //template:begin fromBodyData

func (data *MSDPData) fromBody(ctx context.Context, res gjson.Result) {
	prefix := helpers.LastElement(data.getPath()) + "."
	if res.Get(helpers.LastElement(data.getPath())).IsArray() {
		prefix += "0."
	}
	if value := res.Get(prefix + "originator-id"); value.Exists() {
		data.OriginatorId = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "peer"); value.Exists() {
		data.Peers = make([]MSDPPeers, 0)
		value.ForEach(func(k, v gjson.Result) bool {
			item := MSDPPeers{}
			if cValue := v.Get("addr"); cValue.Exists() {
				item.Addr = types.StringValue(cValue.String())
			}
			if cValue := v.Get("remote-as"); cValue.Exists() {
				item.RemoteAs = types.Int64Value(cValue.Int())
			}
			if cValue := v.Get("connect-source.Loopback"); cValue.Exists() {
				item.ConnectSourceLoopback = types.Int64Value(cValue.Int())
			}
			data.Peers = append(data.Peers, item)
			return true
		})
	}
	if value := res.Get(prefix + "password.peer-list"); value.Exists() {
		data.Passwords = make([]MSDPPasswords, 0)
		value.ForEach(func(k, v gjson.Result) bool {
			item := MSDPPasswords{}
			if cValue := v.Get("addr"); cValue.Exists() {
				item.Addr = types.StringValue(cValue.String())
			}
			if cValue := v.Get("encryption"); cValue.Exists() {
				item.Encryption = types.Int64Value(cValue.Int())
			}
			if cValue := v.Get("password"); cValue.Exists() {
				item.Password = types.StringValue(cValue.String())
			}
			data.Passwords = append(data.Passwords, item)
			return true
		})
	}
	if value := res.Get(prefix + "vrf"); value.Exists() {
		data.Vrfs = make([]MSDPVrfs, 0)
		value.ForEach(func(k, v gjson.Result) bool {
			item := MSDPVrfs{}
			if cValue := v.Get("name"); cValue.Exists() {
				item.Vrf = types.StringValue(cValue.String())
			}
			if cValue := v.Get("originator-id"); cValue.Exists() {
				item.OriginatorId = types.StringValue(cValue.String())
			}
			if cValue := v.Get("peer"); cValue.Exists() {
				item.Peers = make([]MSDPVrfsPeers, 0)
				cValue.ForEach(func(ck, cv gjson.Result) bool {
					cItem := MSDPVrfsPeers{}
					if ccValue := cv.Get("addr"); ccValue.Exists() {
						cItem.Addr = types.StringValue(ccValue.String())
					}
					if ccValue := cv.Get("remote-as"); ccValue.Exists() {
						cItem.RemoteAs = types.Int64Value(ccValue.Int())
					}
					if ccValue := cv.Get("connect-source.Loopback"); ccValue.Exists() {
						cItem.ConnectSourceLoopback = types.Int64Value(ccValue.Int())
					}
					item.Peers = append(item.Peers, cItem)
					return true
				})
			}
			if cValue := v.Get("password.peer-list"); cValue.Exists() {
				item.Passwords = make([]MSDPVrfsPasswords, 0)
				cValue.ForEach(func(ck, cv gjson.Result) bool {
					cItem := MSDPVrfsPasswords{}
					if ccValue := cv.Get("addr"); ccValue.Exists() {
						cItem.Addr = types.StringValue(ccValue.String())
					}
					if ccValue := cv.Get("encryption"); ccValue.Exists() {
						cItem.Encryption = types.Int64Value(ccValue.Int())
					}
					if ccValue := cv.Get("password"); ccValue.Exists() {
						cItem.Password = types.StringValue(ccValue.String())
					}
					item.Passwords = append(item.Passwords, cItem)
					return true
				})
			}
			data.Vrfs = append(data.Vrfs, item)
			return true
		})
	}
}

// End of section. //template:end fromBodyData

// Section below is generated&owned by "gen/generator.go". //template:begin getDeletedItems

func (data *MSDP) getDeletedItems(ctx context.Context, state MSDP) []string {
	deletedItems := make([]string, 0)
	for i := range state.Vrfs {
		stateKeyValues := [...]string{state.Vrfs[i].Vrf.ValueString()}

		emptyKeys := true
		if !reflect.ValueOf(state.Vrfs[i].Vrf.ValueString()).IsZero() {
			emptyKeys = false
		}
		if emptyKeys {
			continue
		}

		found := false
		for j := range data.Vrfs {
			found = true
			if state.Vrfs[i].Vrf.ValueString() != data.Vrfs[j].Vrf.ValueString() {
				found = false
			}
			if found {
				for ci := range state.Vrfs[i].Passwords {
					cstateKeyValues := [...]string{state.Vrfs[i].Passwords[ci].Addr.ValueString()}

					cemptyKeys := true
					if !reflect.ValueOf(state.Vrfs[i].Passwords[ci].Addr.ValueString()).IsZero() {
						cemptyKeys = false
					}
					if cemptyKeys {
						continue
					}

					found := false
					for cj := range data.Vrfs[j].Passwords {
						found = true
						if state.Vrfs[i].Passwords[ci].Addr.ValueString() != data.Vrfs[j].Passwords[cj].Addr.ValueString() {
							found = false
						}
						if found {
							if !state.Vrfs[i].Passwords[ci].Password.IsNull() && data.Vrfs[j].Passwords[cj].Password.IsNull() {
								deletedItems = append(deletedItems, fmt.Sprintf("%v/vrf=%v/password/peer-list=%v/password", state.getPath(), strings.Join(stateKeyValues[:], ","), strings.Join(cstateKeyValues[:], ",")))
							}
							if !state.Vrfs[i].Passwords[ci].Encryption.IsNull() && data.Vrfs[j].Passwords[cj].Encryption.IsNull() {
								deletedItems = append(deletedItems, fmt.Sprintf("%v/vrf=%v/password/peer-list=%v/encryption", state.getPath(), strings.Join(stateKeyValues[:], ","), strings.Join(cstateKeyValues[:], ",")))
							}
							break
						}
					}
					if !found {
						deletedItems = append(deletedItems, fmt.Sprintf("%v/vrf=%v/password/peer-list=%v", state.getPath(), strings.Join(stateKeyValues[:], ","), strings.Join(cstateKeyValues[:], ",")))
					}
				}
				for ci := range state.Vrfs[i].Peers {
					cstateKeyValues := [...]string{state.Vrfs[i].Peers[ci].Addr.ValueString()}

					cemptyKeys := true
					if !reflect.ValueOf(state.Vrfs[i].Peers[ci].Addr.ValueString()).IsZero() {
						cemptyKeys = false
					}
					if cemptyKeys {
						continue
					}

					found := false
					for cj := range data.Vrfs[j].Peers {
						found = true
						if state.Vrfs[i].Peers[ci].Addr.ValueString() != data.Vrfs[j].Peers[cj].Addr.ValueString() {
							found = false
						}
						if found {
							if !state.Vrfs[i].Peers[ci].ConnectSourceLoopback.IsNull() && data.Vrfs[j].Peers[cj].ConnectSourceLoopback.IsNull() {
								deletedItems = append(deletedItems, fmt.Sprintf("%v/vrf=%v/peer=%v/connect-source/Loopback", state.getPath(), strings.Join(stateKeyValues[:], ","), strings.Join(cstateKeyValues[:], ",")))
							}
							if !state.Vrfs[i].Peers[ci].RemoteAs.IsNull() && data.Vrfs[j].Peers[cj].RemoteAs.IsNull() {
								deletedItems = append(deletedItems, fmt.Sprintf("%v/vrf=%v/peer=%v/remote-as", state.getPath(), strings.Join(stateKeyValues[:], ","), strings.Join(cstateKeyValues[:], ",")))
							}
							break
						}
					}
					if !found {
						deletedItems = append(deletedItems, fmt.Sprintf("%v/vrf=%v/peer=%v", state.getPath(), strings.Join(stateKeyValues[:], ","), strings.Join(cstateKeyValues[:], ",")))
					}
				}
				if !state.Vrfs[i].OriginatorId.IsNull() && data.Vrfs[j].OriginatorId.IsNull() {
					deletedItems = append(deletedItems, fmt.Sprintf("%v/vrf=%v/originator-id", state.getPath(), strings.Join(stateKeyValues[:], ",")))
				}
				break
			}
		}
		if !found {
			deletedItems = append(deletedItems, fmt.Sprintf("%v/vrf=%v", state.getPath(), strings.Join(stateKeyValues[:], ",")))
		}
	}
	for i := range state.Passwords {
		stateKeyValues := [...]string{state.Passwords[i].Addr.ValueString()}

		emptyKeys := true
		if !reflect.ValueOf(state.Passwords[i].Addr.ValueString()).IsZero() {
			emptyKeys = false
		}
		if emptyKeys {
			continue
		}

		found := false
		for j := range data.Passwords {
			found = true
			if state.Passwords[i].Addr.ValueString() != data.Passwords[j].Addr.ValueString() {
				found = false
			}
			if found {
				if !state.Passwords[i].Password.IsNull() && data.Passwords[j].Password.IsNull() {
					deletedItems = append(deletedItems, fmt.Sprintf("%v/password/peer-list=%v/password", state.getPath(), strings.Join(stateKeyValues[:], ",")))
				}
				if !state.Passwords[i].Encryption.IsNull() && data.Passwords[j].Encryption.IsNull() {
					deletedItems = append(deletedItems, fmt.Sprintf("%v/password/peer-list=%v/encryption", state.getPath(), strings.Join(stateKeyValues[:], ",")))
				}
				break
			}
		}
		if !found {
			deletedItems = append(deletedItems, fmt.Sprintf("%v/password/peer-list=%v", state.getPath(), strings.Join(stateKeyValues[:], ",")))
		}
	}
	for i := range state.Peers {
		stateKeyValues := [...]string{state.Peers[i].Addr.ValueString()}

		emptyKeys := true
		if !reflect.ValueOf(state.Peers[i].Addr.ValueString()).IsZero() {
			emptyKeys = false
		}
		if emptyKeys {
			continue
		}

		found := false
		for j := range data.Peers {
			found = true
			if state.Peers[i].Addr.ValueString() != data.Peers[j].Addr.ValueString() {
				found = false
			}
			if found {
				if !state.Peers[i].ConnectSourceLoopback.IsNull() && data.Peers[j].ConnectSourceLoopback.IsNull() {
					deletedItems = append(deletedItems, fmt.Sprintf("%v/peer=%v/connect-source/Loopback", state.getPath(), strings.Join(stateKeyValues[:], ",")))
				}
				if !state.Peers[i].RemoteAs.IsNull() && data.Peers[j].RemoteAs.IsNull() {
					deletedItems = append(deletedItems, fmt.Sprintf("%v/peer=%v/remote-as", state.getPath(), strings.Join(stateKeyValues[:], ",")))
				}
				break
			}
		}
		if !found {
			deletedItems = append(deletedItems, fmt.Sprintf("%v/peer=%v", state.getPath(), strings.Join(stateKeyValues[:], ",")))
		}
	}
	if !state.OriginatorId.IsNull() && data.OriginatorId.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/originator-id", state.getPath()))
	}

	return deletedItems
}

// End of section. //template:end getDeletedItems

// Section below is generated&owned by "gen/generator.go". //template:begin getEmptyLeafsDelete

func (data *MSDP) getEmptyLeafsDelete(ctx context.Context) []string {
	emptyLeafsDelete := make([]string, 0)

	return emptyLeafsDelete
}

// End of section. //template:end getEmptyLeafsDelete

// Section below is generated&owned by "gen/generator.go". //template:begin getDeletePaths

func (data *MSDP) getDeletePaths(ctx context.Context) []string {
	var deletePaths []string
	for i := range data.Vrfs {
		keyValues := [...]string{data.Vrfs[i].Vrf.ValueString()}

		deletePaths = append(deletePaths, fmt.Sprintf("%v/vrf=%v", data.getPath(), strings.Join(keyValues[:], ",")))
	}
	for i := range data.Passwords {
		keyValues := [...]string{data.Passwords[i].Addr.ValueString()}

		deletePaths = append(deletePaths, fmt.Sprintf("%v/password/peer-list=%v", data.getPath(), strings.Join(keyValues[:], ",")))
	}
	for i := range data.Peers {
		keyValues := [...]string{data.Peers[i].Addr.ValueString()}

		deletePaths = append(deletePaths, fmt.Sprintf("%v/peer=%v", data.getPath(), strings.Join(keyValues[:], ",")))
	}
	if !data.OriginatorId.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/originator-id", data.getPath()))
	}

	return deletePaths
}

// End of section. //template:end getDeletePaths
