// 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"
	"net/url"
	"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 ServiceTemplate struct {
	Device                  types.String                        `tfsdk:"device"`
	Id                      types.String                        `tfsdk:"id"`
	Name                    types.String                        `tfsdk:"name"`
	AccessGroups            []ServiceTemplateAccessGroups       `tfsdk:"access_groups"`
	InactivityTimer         types.Int64                         `tfsdk:"inactivity_timer"`
	InactivityTimerProbe    types.Bool                          `tfsdk:"inactivity_timer_probe"`
	Vlan                    types.Int64                         `tfsdk:"vlan"`
	VoiceVlan               types.Bool                          `tfsdk:"voice_vlan"`
	LinksecPolicy           types.String                        `tfsdk:"linksec_policy"`
	Sgt                     types.Int64                         `tfsdk:"sgt"`
	AbsoluteTimer           types.Int64                         `tfsdk:"absolute_timer"`
	Description             types.String                        `tfsdk:"description"`
	InterfaceTemplates      []ServiceTemplateInterfaceTemplates `tfsdk:"interface_templates"`
	TunnelCapwapName        types.String                        `tfsdk:"tunnel_capwap_name"`
	Vnid                    types.String                        `tfsdk:"vnid"`
	RedirectAppendClientMac types.String                        `tfsdk:"redirect_append_client_mac"`
	RedirectAppendSwitchMac types.String                        `tfsdk:"redirect_append_switch_mac"`
	RedirectUrl             types.String                        `tfsdk:"redirect_url"`
	RedirectUrlMatchAcl     types.String                        `tfsdk:"redirect_url_match_acl"`
	RedirectUrlMatchAction  types.String                        `tfsdk:"redirect_url_match_action"`
	DnsAclPreauth           types.String                        `tfsdk:"dns_acl_preauth"`
	ServicePolicyQosInput   types.String                        `tfsdk:"service_policy_qos_input"`
	ServicePolicyQosOutput  types.String                        `tfsdk:"service_policy_qos_output"`
	Tags                    []ServiceTemplateTags               `tfsdk:"tags"`
	MdnsServicePolicy       types.String                        `tfsdk:"mdns_service_policy"`
}

type ServiceTemplateData struct {
	Device                  types.String                        `tfsdk:"device"`
	Id                      types.String                        `tfsdk:"id"`
	Name                    types.String                        `tfsdk:"name"`
	AccessGroups            []ServiceTemplateAccessGroups       `tfsdk:"access_groups"`
	InactivityTimer         types.Int64                         `tfsdk:"inactivity_timer"`
	InactivityTimerProbe    types.Bool                          `tfsdk:"inactivity_timer_probe"`
	Vlan                    types.Int64                         `tfsdk:"vlan"`
	VoiceVlan               types.Bool                          `tfsdk:"voice_vlan"`
	LinksecPolicy           types.String                        `tfsdk:"linksec_policy"`
	Sgt                     types.Int64                         `tfsdk:"sgt"`
	AbsoluteTimer           types.Int64                         `tfsdk:"absolute_timer"`
	Description             types.String                        `tfsdk:"description"`
	InterfaceTemplates      []ServiceTemplateInterfaceTemplates `tfsdk:"interface_templates"`
	TunnelCapwapName        types.String                        `tfsdk:"tunnel_capwap_name"`
	Vnid                    types.String                        `tfsdk:"vnid"`
	RedirectAppendClientMac types.String                        `tfsdk:"redirect_append_client_mac"`
	RedirectAppendSwitchMac types.String                        `tfsdk:"redirect_append_switch_mac"`
	RedirectUrl             types.String                        `tfsdk:"redirect_url"`
	RedirectUrlMatchAcl     types.String                        `tfsdk:"redirect_url_match_acl"`
	RedirectUrlMatchAction  types.String                        `tfsdk:"redirect_url_match_action"`
	DnsAclPreauth           types.String                        `tfsdk:"dns_acl_preauth"`
	ServicePolicyQosInput   types.String                        `tfsdk:"service_policy_qos_input"`
	ServicePolicyQosOutput  types.String                        `tfsdk:"service_policy_qos_output"`
	Tags                    []ServiceTemplateTags               `tfsdk:"tags"`
	MdnsServicePolicy       types.String                        `tfsdk:"mdns_service_policy"`
}
type ServiceTemplateAccessGroups struct {
	Name types.String `tfsdk:"name"`
}
type ServiceTemplateInterfaceTemplates struct {
	Name types.String `tfsdk:"name"`
}
type ServiceTemplateTags struct {
	Name types.String `tfsdk:"name"`
}

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

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

func (data ServiceTemplate) getPath() string {
	return fmt.Sprintf("Cisco-IOS-XE-native:native/Cisco-IOS-XE-switch:service-template=%v", url.QueryEscape(fmt.Sprintf("%v", data.Name.ValueString())))
}

func (data ServiceTemplateData) getPath() string {
	return fmt.Sprintf("Cisco-IOS-XE-native:native/Cisco-IOS-XE-switch:service-template=%v", url.QueryEscape(fmt.Sprintf("%v", data.Name.ValueString())))
}

// if last path element has a key -> remove it
func (data ServiceTemplate) 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 ServiceTemplate) toBody(ctx context.Context) string {
	body := `{"` + helpers.LastElement(data.getPath()) + `":{}}`
	if !data.Name.IsNull() && !data.Name.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"word", data.Name.ValueString())
	}
	if !data.InactivityTimer.IsNull() && !data.InactivityTimer.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"inactivity-timer.value", strconv.FormatInt(data.InactivityTimer.ValueInt64(), 10))
	}
	if !data.InactivityTimerProbe.IsNull() && !data.InactivityTimerProbe.IsUnknown() {
		if data.InactivityTimerProbe.ValueBool() {
			body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"inactivity-timer.probe", map[string]string{})
		}
	}
	if !data.Vlan.IsNull() && !data.Vlan.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"vlan", strconv.FormatInt(data.Vlan.ValueInt64(), 10))
	}
	if !data.VoiceVlan.IsNull() && !data.VoiceVlan.IsUnknown() {
		if data.VoiceVlan.ValueBool() {
			body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"voice.vlan", map[string]string{})
		}
	}
	if !data.LinksecPolicy.IsNull() && !data.LinksecPolicy.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"linksec.policy", data.LinksecPolicy.ValueString())
	}
	if !data.Sgt.IsNull() && !data.Sgt.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"sgt", strconv.FormatInt(data.Sgt.ValueInt64(), 10))
	}
	if !data.AbsoluteTimer.IsNull() && !data.AbsoluteTimer.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"absolute-timer", strconv.FormatInt(data.AbsoluteTimer.ValueInt64(), 10))
	}
	if !data.Description.IsNull() && !data.Description.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"description", data.Description.ValueString())
	}
	if !data.TunnelCapwapName.IsNull() && !data.TunnelCapwapName.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"tunnel.type.capwap.name", data.TunnelCapwapName.ValueString())
	}
	if !data.Vnid.IsNull() && !data.Vnid.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"vnid", data.Vnid.ValueString())
	}
	if !data.RedirectAppendClientMac.IsNull() && !data.RedirectAppendClientMac.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"redirect.append.client-mac", data.RedirectAppendClientMac.ValueString())
	}
	if !data.RedirectAppendSwitchMac.IsNull() && !data.RedirectAppendSwitchMac.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"redirect.append.switch-mac", data.RedirectAppendSwitchMac.ValueString())
	}
	if !data.RedirectUrl.IsNull() && !data.RedirectUrl.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"redirect.url.url_name", data.RedirectUrl.ValueString())
	}
	if !data.RedirectUrlMatchAcl.IsNull() && !data.RedirectUrlMatchAcl.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"redirect.url.match.acl_name", data.RedirectUrlMatchAcl.ValueString())
	}
	if !data.RedirectUrlMatchAction.IsNull() && !data.RedirectUrlMatchAction.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"redirect.url.match.action", data.RedirectUrlMatchAction.ValueString())
	}
	if !data.DnsAclPreauth.IsNull() && !data.DnsAclPreauth.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"dns-acl.preauth", data.DnsAclPreauth.ValueString())
	}
	if !data.ServicePolicyQosInput.IsNull() && !data.ServicePolicyQosInput.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"service-policy.qos.input", data.ServicePolicyQosInput.ValueString())
	}
	if !data.ServicePolicyQosOutput.IsNull() && !data.ServicePolicyQosOutput.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"service-policy.qos.output", data.ServicePolicyQosOutput.ValueString())
	}
	if !data.MdnsServicePolicy.IsNull() && !data.MdnsServicePolicy.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"mdns-service-policy", data.MdnsServicePolicy.ValueString())
	}
	if len(data.AccessGroups) > 0 {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"access-group-config", []interface{}{})
		for index, item := range data.AccessGroups {
			if !item.Name.IsNull() && !item.Name.IsUnknown() {
				body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"access-group-config"+"."+strconv.Itoa(index)+"."+"name", item.Name.ValueString())
			}
		}
	}
	if len(data.InterfaceTemplates) > 0 {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"interface-template", []interface{}{})
		for index, item := range data.InterfaceTemplates {
			if !item.Name.IsNull() && !item.Name.IsUnknown() {
				body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"interface-template"+"."+strconv.Itoa(index)+"."+"name", item.Name.ValueString())
			}
		}
	}
	if len(data.Tags) > 0 {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"tag-config", []interface{}{})
		for index, item := range data.Tags {
			if !item.Name.IsNull() && !item.Name.IsUnknown() {
				body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"tag-config"+"."+strconv.Itoa(index)+"."+"name", item.Name.ValueString())
			}
		}
	}
	return body
}

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

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

func (data *ServiceTemplate) 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 + "word"); value.Exists() && !data.Name.IsNull() {
		data.Name = types.StringValue(value.String())
	} else {
		data.Name = types.StringNull()
	}
	for i := range data.AccessGroups {
		keys := [...]string{"name"}
		keyValues := [...]string{data.AccessGroups[i].Name.ValueString()}

		var r gjson.Result
		res.Get(prefix + "access-group-config").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.AccessGroups[i].Name.IsNull() {
			data.AccessGroups[i].Name = types.StringValue(value.String())
		} else {
			data.AccessGroups[i].Name = types.StringNull()
		}
	}
	if value := res.Get(prefix + "inactivity-timer.value"); value.Exists() && !data.InactivityTimer.IsNull() {
		data.InactivityTimer = types.Int64Value(value.Int())
	} else {
		data.InactivityTimer = types.Int64Null()
	}
	if value := res.Get(prefix + "inactivity-timer.probe"); !data.InactivityTimerProbe.IsNull() {
		if value.Exists() {
			data.InactivityTimerProbe = types.BoolValue(true)
		} else {
			data.InactivityTimerProbe = types.BoolValue(false)
		}
	} else {
		data.InactivityTimerProbe = types.BoolNull()
	}
	if value := res.Get(prefix + "vlan"); value.Exists() && !data.Vlan.IsNull() {
		data.Vlan = types.Int64Value(value.Int())
	} else {
		data.Vlan = types.Int64Null()
	}
	if value := res.Get(prefix + "voice.vlan"); !data.VoiceVlan.IsNull() {
		if value.Exists() {
			data.VoiceVlan = types.BoolValue(true)
		} else {
			data.VoiceVlan = types.BoolValue(false)
		}
	} else {
		data.VoiceVlan = types.BoolNull()
	}
	if value := res.Get(prefix + "linksec.policy"); value.Exists() && !data.LinksecPolicy.IsNull() {
		data.LinksecPolicy = types.StringValue(value.String())
	} else {
		data.LinksecPolicy = types.StringNull()
	}
	if value := res.Get(prefix + "sgt"); value.Exists() && !data.Sgt.IsNull() {
		data.Sgt = types.Int64Value(value.Int())
	} else {
		data.Sgt = types.Int64Null()
	}
	if value := res.Get(prefix + "absolute-timer"); value.Exists() && !data.AbsoluteTimer.IsNull() {
		data.AbsoluteTimer = types.Int64Value(value.Int())
	} else {
		data.AbsoluteTimer = types.Int64Null()
	}
	if value := res.Get(prefix + "description"); value.Exists() && !data.Description.IsNull() {
		data.Description = types.StringValue(value.String())
	} else {
		data.Description = types.StringNull()
	}
	for i := range data.InterfaceTemplates {
		keys := [...]string{"name"}
		keyValues := [...]string{data.InterfaceTemplates[i].Name.ValueString()}

		var r gjson.Result
		res.Get(prefix + "interface-template").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.InterfaceTemplates[i].Name.IsNull() {
			data.InterfaceTemplates[i].Name = types.StringValue(value.String())
		} else {
			data.InterfaceTemplates[i].Name = types.StringNull()
		}
	}
	if value := res.Get(prefix + "tunnel.type.capwap.name"); value.Exists() && !data.TunnelCapwapName.IsNull() {
		data.TunnelCapwapName = types.StringValue(value.String())
	} else {
		data.TunnelCapwapName = types.StringNull()
	}
	if value := res.Get(prefix + "vnid"); value.Exists() && !data.Vnid.IsNull() {
		data.Vnid = types.StringValue(value.String())
	} else {
		data.Vnid = types.StringNull()
	}
	if value := res.Get(prefix + "redirect.append.client-mac"); value.Exists() && !data.RedirectAppendClientMac.IsNull() {
		data.RedirectAppendClientMac = types.StringValue(value.String())
	} else {
		data.RedirectAppendClientMac = types.StringNull()
	}
	if value := res.Get(prefix + "redirect.append.switch-mac"); value.Exists() && !data.RedirectAppendSwitchMac.IsNull() {
		data.RedirectAppendSwitchMac = types.StringValue(value.String())
	} else {
		data.RedirectAppendSwitchMac = types.StringNull()
	}
	if value := res.Get(prefix + "redirect.url.url_name"); value.Exists() && !data.RedirectUrl.IsNull() {
		data.RedirectUrl = types.StringValue(value.String())
	} else {
		data.RedirectUrl = types.StringNull()
	}
	if value := res.Get(prefix + "redirect.url.match.acl_name"); value.Exists() && !data.RedirectUrlMatchAcl.IsNull() {
		data.RedirectUrlMatchAcl = types.StringValue(value.String())
	} else {
		data.RedirectUrlMatchAcl = types.StringNull()
	}
	if value := res.Get(prefix + "redirect.url.match.action"); value.Exists() && !data.RedirectUrlMatchAction.IsNull() {
		data.RedirectUrlMatchAction = types.StringValue(value.String())
	} else {
		data.RedirectUrlMatchAction = types.StringNull()
	}
	if value := res.Get(prefix + "dns-acl.preauth"); value.Exists() && !data.DnsAclPreauth.IsNull() {
		data.DnsAclPreauth = types.StringValue(value.String())
	} else {
		data.DnsAclPreauth = types.StringNull()
	}
	if value := res.Get(prefix + "service-policy.qos.input"); value.Exists() && !data.ServicePolicyQosInput.IsNull() {
		data.ServicePolicyQosInput = types.StringValue(value.String())
	} else {
		data.ServicePolicyQosInput = types.StringNull()
	}
	if value := res.Get(prefix + "service-policy.qos.output"); value.Exists() && !data.ServicePolicyQosOutput.IsNull() {
		data.ServicePolicyQosOutput = types.StringValue(value.String())
	} else {
		data.ServicePolicyQosOutput = types.StringNull()
	}
	for i := range data.Tags {
		keys := [...]string{"name"}
		keyValues := [...]string{data.Tags[i].Name.ValueString()}

		var r gjson.Result
		res.Get(prefix + "tag-config").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.Tags[i].Name.IsNull() {
			data.Tags[i].Name = types.StringValue(value.String())
		} else {
			data.Tags[i].Name = types.StringNull()
		}
	}
	if value := res.Get(prefix + "mdns-service-policy"); value.Exists() && !data.MdnsServicePolicy.IsNull() {
		data.MdnsServicePolicy = types.StringValue(value.String())
	} else {
		data.MdnsServicePolicy = types.StringNull()
	}
}

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

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

func (data *ServiceTemplate) 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 + "access-group-config"); value.Exists() {
		data.AccessGroups = make([]ServiceTemplateAccessGroups, 0)
		value.ForEach(func(k, v gjson.Result) bool {
			item := ServiceTemplateAccessGroups{}
			if cValue := v.Get("name"); cValue.Exists() {
				item.Name = types.StringValue(cValue.String())
			}
			data.AccessGroups = append(data.AccessGroups, item)
			return true
		})
	}
	if value := res.Get(prefix + "inactivity-timer.value"); value.Exists() {
		data.InactivityTimer = types.Int64Value(value.Int())
	}
	if value := res.Get(prefix + "inactivity-timer.probe"); value.Exists() {
		data.InactivityTimerProbe = types.BoolValue(true)
	} else {
		data.InactivityTimerProbe = types.BoolValue(false)
	}
	if value := res.Get(prefix + "vlan"); value.Exists() {
		data.Vlan = types.Int64Value(value.Int())
	}
	if value := res.Get(prefix + "voice.vlan"); value.Exists() {
		data.VoiceVlan = types.BoolValue(true)
	} else {
		data.VoiceVlan = types.BoolValue(false)
	}
	if value := res.Get(prefix + "linksec.policy"); value.Exists() {
		data.LinksecPolicy = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "sgt"); value.Exists() {
		data.Sgt = types.Int64Value(value.Int())
	}
	if value := res.Get(prefix + "absolute-timer"); value.Exists() {
		data.AbsoluteTimer = types.Int64Value(value.Int())
	}
	if value := res.Get(prefix + "description"); value.Exists() {
		data.Description = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "interface-template"); value.Exists() {
		data.InterfaceTemplates = make([]ServiceTemplateInterfaceTemplates, 0)
		value.ForEach(func(k, v gjson.Result) bool {
			item := ServiceTemplateInterfaceTemplates{}
			if cValue := v.Get("name"); cValue.Exists() {
				item.Name = types.StringValue(cValue.String())
			}
			data.InterfaceTemplates = append(data.InterfaceTemplates, item)
			return true
		})
	}
	if value := res.Get(prefix + "tunnel.type.capwap.name"); value.Exists() {
		data.TunnelCapwapName = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "vnid"); value.Exists() {
		data.Vnid = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "redirect.append.client-mac"); value.Exists() {
		data.RedirectAppendClientMac = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "redirect.append.switch-mac"); value.Exists() {
		data.RedirectAppendSwitchMac = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "redirect.url.url_name"); value.Exists() {
		data.RedirectUrl = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "redirect.url.match.acl_name"); value.Exists() {
		data.RedirectUrlMatchAcl = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "redirect.url.match.action"); value.Exists() {
		data.RedirectUrlMatchAction = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "dns-acl.preauth"); value.Exists() {
		data.DnsAclPreauth = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "service-policy.qos.input"); value.Exists() {
		data.ServicePolicyQosInput = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "service-policy.qos.output"); value.Exists() {
		data.ServicePolicyQosOutput = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "tag-config"); value.Exists() {
		data.Tags = make([]ServiceTemplateTags, 0)
		value.ForEach(func(k, v gjson.Result) bool {
			item := ServiceTemplateTags{}
			if cValue := v.Get("name"); cValue.Exists() {
				item.Name = types.StringValue(cValue.String())
			}
			data.Tags = append(data.Tags, item)
			return true
		})
	}
	if value := res.Get(prefix + "mdns-service-policy"); value.Exists() {
		data.MdnsServicePolicy = types.StringValue(value.String())
	}
}

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

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

func (data *ServiceTemplateData) 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 + "access-group-config"); value.Exists() {
		data.AccessGroups = make([]ServiceTemplateAccessGroups, 0)
		value.ForEach(func(k, v gjson.Result) bool {
			item := ServiceTemplateAccessGroups{}
			if cValue := v.Get("name"); cValue.Exists() {
				item.Name = types.StringValue(cValue.String())
			}
			data.AccessGroups = append(data.AccessGroups, item)
			return true
		})
	}
	if value := res.Get(prefix + "inactivity-timer.value"); value.Exists() {
		data.InactivityTimer = types.Int64Value(value.Int())
	}
	if value := res.Get(prefix + "inactivity-timer.probe"); value.Exists() {
		data.InactivityTimerProbe = types.BoolValue(true)
	} else {
		data.InactivityTimerProbe = types.BoolValue(false)
	}
	if value := res.Get(prefix + "vlan"); value.Exists() {
		data.Vlan = types.Int64Value(value.Int())
	}
	if value := res.Get(prefix + "voice.vlan"); value.Exists() {
		data.VoiceVlan = types.BoolValue(true)
	} else {
		data.VoiceVlan = types.BoolValue(false)
	}
	if value := res.Get(prefix + "linksec.policy"); value.Exists() {
		data.LinksecPolicy = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "sgt"); value.Exists() {
		data.Sgt = types.Int64Value(value.Int())
	}
	if value := res.Get(prefix + "absolute-timer"); value.Exists() {
		data.AbsoluteTimer = types.Int64Value(value.Int())
	}
	if value := res.Get(prefix + "description"); value.Exists() {
		data.Description = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "interface-template"); value.Exists() {
		data.InterfaceTemplates = make([]ServiceTemplateInterfaceTemplates, 0)
		value.ForEach(func(k, v gjson.Result) bool {
			item := ServiceTemplateInterfaceTemplates{}
			if cValue := v.Get("name"); cValue.Exists() {
				item.Name = types.StringValue(cValue.String())
			}
			data.InterfaceTemplates = append(data.InterfaceTemplates, item)
			return true
		})
	}
	if value := res.Get(prefix + "tunnel.type.capwap.name"); value.Exists() {
		data.TunnelCapwapName = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "vnid"); value.Exists() {
		data.Vnid = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "redirect.append.client-mac"); value.Exists() {
		data.RedirectAppendClientMac = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "redirect.append.switch-mac"); value.Exists() {
		data.RedirectAppendSwitchMac = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "redirect.url.url_name"); value.Exists() {
		data.RedirectUrl = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "redirect.url.match.acl_name"); value.Exists() {
		data.RedirectUrlMatchAcl = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "redirect.url.match.action"); value.Exists() {
		data.RedirectUrlMatchAction = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "dns-acl.preauth"); value.Exists() {
		data.DnsAclPreauth = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "service-policy.qos.input"); value.Exists() {
		data.ServicePolicyQosInput = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "service-policy.qos.output"); value.Exists() {
		data.ServicePolicyQosOutput = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "tag-config"); value.Exists() {
		data.Tags = make([]ServiceTemplateTags, 0)
		value.ForEach(func(k, v gjson.Result) bool {
			item := ServiceTemplateTags{}
			if cValue := v.Get("name"); cValue.Exists() {
				item.Name = types.StringValue(cValue.String())
			}
			data.Tags = append(data.Tags, item)
			return true
		})
	}
	if value := res.Get(prefix + "mdns-service-policy"); value.Exists() {
		data.MdnsServicePolicy = types.StringValue(value.String())
	}
}

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

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

func (data *ServiceTemplate) getDeletedItems(ctx context.Context, state ServiceTemplate) []string {
	deletedItems := make([]string, 0)
	if !state.MdnsServicePolicy.IsNull() && data.MdnsServicePolicy.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/mdns-service-policy", state.getPath()))
	}
	for i := range state.Tags {
		stateKeyValues := [...]string{state.Tags[i].Name.ValueString()}

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

		found := false
		for j := range data.Tags {
			found = true
			if state.Tags[i].Name.ValueString() != data.Tags[j].Name.ValueString() {
				found = false
			}
			if found {
				break
			}
		}
		if !found {
			deletedItems = append(deletedItems, fmt.Sprintf("%v/tag-config=%v", state.getPath(), strings.Join(stateKeyValues[:], ",")))
		}
	}
	if !state.ServicePolicyQosOutput.IsNull() && data.ServicePolicyQosOutput.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/service-policy/qos/output", state.getPath()))
	}
	if !state.ServicePolicyQosInput.IsNull() && data.ServicePolicyQosInput.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/service-policy/qos/input", state.getPath()))
	}
	if !state.DnsAclPreauth.IsNull() && data.DnsAclPreauth.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/dns-acl/preauth", state.getPath()))
	}
	if !state.RedirectUrlMatchAction.IsNull() && data.RedirectUrlMatchAction.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/redirect/url/match/action", state.getPath()))
	}
	if !state.RedirectUrlMatchAcl.IsNull() && data.RedirectUrlMatchAcl.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/redirect/url/match/acl_name", state.getPath()))
	}
	if !state.RedirectUrl.IsNull() && data.RedirectUrl.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/redirect/url/url_name", state.getPath()))
	}
	if !state.RedirectAppendSwitchMac.IsNull() && data.RedirectAppendSwitchMac.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/redirect/append/switch-mac", state.getPath()))
	}
	if !state.RedirectAppendClientMac.IsNull() && data.RedirectAppendClientMac.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/redirect/append/client-mac", state.getPath()))
	}
	if !state.Vnid.IsNull() && data.Vnid.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/vnid", state.getPath()))
	}
	if !state.TunnelCapwapName.IsNull() && data.TunnelCapwapName.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/tunnel/type/capwap/name", state.getPath()))
	}
	for i := range state.InterfaceTemplates {
		stateKeyValues := [...]string{state.InterfaceTemplates[i].Name.ValueString()}

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

		found := false
		for j := range data.InterfaceTemplates {
			found = true
			if state.InterfaceTemplates[i].Name.ValueString() != data.InterfaceTemplates[j].Name.ValueString() {
				found = false
			}
			if found {
				break
			}
		}
		if !found {
			deletedItems = append(deletedItems, fmt.Sprintf("%v/interface-template=%v", state.getPath(), strings.Join(stateKeyValues[:], ",")))
		}
	}
	if !state.Description.IsNull() && data.Description.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/description", state.getPath()))
	}
	if !state.AbsoluteTimer.IsNull() && data.AbsoluteTimer.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/absolute-timer", state.getPath()))
	}
	if !state.Sgt.IsNull() && data.Sgt.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/sgt", state.getPath()))
	}
	if !state.LinksecPolicy.IsNull() && data.LinksecPolicy.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/linksec/policy", state.getPath()))
	}
	if !state.VoiceVlan.IsNull() && data.VoiceVlan.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/voice/vlan", state.getPath()))
	}
	if !state.Vlan.IsNull() && data.Vlan.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/vlan", state.getPath()))
	}
	if !state.InactivityTimerProbe.IsNull() && data.InactivityTimerProbe.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/inactivity-timer/probe", state.getPath()))
	}
	if !state.InactivityTimer.IsNull() && data.InactivityTimer.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/inactivity-timer/value", state.getPath()))
	}
	for i := range state.AccessGroups {
		stateKeyValues := [...]string{state.AccessGroups[i].Name.ValueString()}

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

		found := false
		for j := range data.AccessGroups {
			found = true
			if state.AccessGroups[i].Name.ValueString() != data.AccessGroups[j].Name.ValueString() {
				found = false
			}
			if found {
				break
			}
		}
		if !found {
			deletedItems = append(deletedItems, fmt.Sprintf("%v/access-group-config=%v", state.getPath(), strings.Join(stateKeyValues[:], ",")))
		}
	}

	return deletedItems
}

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

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

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

	if !data.VoiceVlan.IsNull() && !data.VoiceVlan.ValueBool() {
		emptyLeafsDelete = append(emptyLeafsDelete, fmt.Sprintf("%v/voice/vlan", data.getPath()))
	}
	if !data.InactivityTimerProbe.IsNull() && !data.InactivityTimerProbe.ValueBool() {
		emptyLeafsDelete = append(emptyLeafsDelete, fmt.Sprintf("%v/inactivity-timer/probe", data.getPath()))
	}

	return emptyLeafsDelete
}

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

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

func (data *ServiceTemplate) getDeletePaths(ctx context.Context) []string {
	var deletePaths []string
	if !data.MdnsServicePolicy.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/mdns-service-policy", data.getPath()))
	}
	for i := range data.Tags {
		keyValues := [...]string{data.Tags[i].Name.ValueString()}

		deletePaths = append(deletePaths, fmt.Sprintf("%v/tag-config=%v", data.getPath(), strings.Join(keyValues[:], ",")))
	}
	if !data.ServicePolicyQosOutput.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/service-policy/qos/output", data.getPath()))
	}
	if !data.ServicePolicyQosInput.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/service-policy/qos/input", data.getPath()))
	}
	if !data.DnsAclPreauth.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/dns-acl/preauth", data.getPath()))
	}
	if !data.RedirectUrlMatchAction.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/redirect/url/match/action", data.getPath()))
	}
	if !data.RedirectUrlMatchAcl.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/redirect/url/match/acl_name", data.getPath()))
	}
	if !data.RedirectUrl.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/redirect/url/url_name", data.getPath()))
	}
	if !data.RedirectAppendSwitchMac.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/redirect/append/switch-mac", data.getPath()))
	}
	if !data.RedirectAppendClientMac.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/redirect/append/client-mac", data.getPath()))
	}
	if !data.Vnid.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/vnid", data.getPath()))
	}
	if !data.TunnelCapwapName.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/tunnel/type/capwap/name", data.getPath()))
	}
	for i := range data.InterfaceTemplates {
		keyValues := [...]string{data.InterfaceTemplates[i].Name.ValueString()}

		deletePaths = append(deletePaths, fmt.Sprintf("%v/interface-template=%v", data.getPath(), strings.Join(keyValues[:], ",")))
	}
	if !data.Description.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/description", data.getPath()))
	}
	if !data.AbsoluteTimer.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/absolute-timer", data.getPath()))
	}
	if !data.Sgt.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/sgt", data.getPath()))
	}
	if !data.LinksecPolicy.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/linksec/policy", data.getPath()))
	}
	if !data.VoiceVlan.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/voice/vlan", data.getPath()))
	}
	if !data.Vlan.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/vlan", data.getPath()))
	}
	if !data.InactivityTimerProbe.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/inactivity-timer/probe", data.getPath()))
	}
	if !data.InactivityTimer.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/inactivity-timer/value", data.getPath()))
	}
	for i := range data.AccessGroups {
		keyValues := [...]string{data.AccessGroups[i].Name.ValueString()}

		deletePaths = append(deletePaths, fmt.Sprintf("%v/access-group-config=%v", data.getPath(), strings.Join(keyValues[:], ",")))
	}

	return deletePaths
}

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