// 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"
	"regexp"
	"strconv"

	"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 FlowExporter struct {
	Device                             types.String `tfsdk:"device"`
	Id                                 types.String `tfsdk:"id"`
	DeleteMode                         types.String `tfsdk:"delete_mode"`
	Name                               types.String `tfsdk:"name"`
	Description                        types.String `tfsdk:"description"`
	DestinationIp                      types.String `tfsdk:"destination_ip"`
	SourceLoopback                     types.Int64  `tfsdk:"source_loopback"`
	TransportUdp                       types.Int64  `tfsdk:"transport_udp"`
	TemplateDataTimeout                types.Int64  `tfsdk:"template_data_timeout"`
	ExportProtocol                     types.String `tfsdk:"export_protocol"`
	OptionInterfaceTableTimeout        types.Int64  `tfsdk:"option_interface_table_timeout"`
	OptionVrfTableTimeout              types.Int64  `tfsdk:"option_vrf_table_timeout"`
	OptionSamplerTable                 types.Bool   `tfsdk:"option_sampler_table"`
	OptionApplicationTableTimeout      types.Int64  `tfsdk:"option_application_table_timeout"`
	OptionApplicationAttributesTimeout types.Int64  `tfsdk:"option_application_attributes_timeout"`
}

type FlowExporterData struct {
	Device                             types.String `tfsdk:"device"`
	Id                                 types.String `tfsdk:"id"`
	Name                               types.String `tfsdk:"name"`
	Description                        types.String `tfsdk:"description"`
	DestinationIp                      types.String `tfsdk:"destination_ip"`
	SourceLoopback                     types.Int64  `tfsdk:"source_loopback"`
	TransportUdp                       types.Int64  `tfsdk:"transport_udp"`
	TemplateDataTimeout                types.Int64  `tfsdk:"template_data_timeout"`
	ExportProtocol                     types.String `tfsdk:"export_protocol"`
	OptionInterfaceTableTimeout        types.Int64  `tfsdk:"option_interface_table_timeout"`
	OptionVrfTableTimeout              types.Int64  `tfsdk:"option_vrf_table_timeout"`
	OptionSamplerTable                 types.Bool   `tfsdk:"option_sampler_table"`
	OptionApplicationTableTimeout      types.Int64  `tfsdk:"option_application_table_timeout"`
	OptionApplicationAttributesTimeout types.Int64  `tfsdk:"option_application_attributes_timeout"`
}

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

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

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

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

// if last path element has a key -> remove it
func (data FlowExporter) 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 FlowExporter) 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())+"."+"name", data.Name.ValueString())
	}
	if !data.Description.IsNull() && !data.Description.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"description", data.Description.ValueString())
	}
	if !data.DestinationIp.IsNull() && !data.DestinationIp.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"destination.ipdest.ip", data.DestinationIp.ValueString())
	}
	if !data.SourceLoopback.IsNull() && !data.SourceLoopback.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"source.Loopback", strconv.FormatInt(data.SourceLoopback.ValueInt64(), 10))
	}
	if !data.TransportUdp.IsNull() && !data.TransportUdp.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"transport.udp", strconv.FormatInt(data.TransportUdp.ValueInt64(), 10))
	}
	if !data.TemplateDataTimeout.IsNull() && !data.TemplateDataTimeout.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"template.data.timeout", strconv.FormatInt(data.TemplateDataTimeout.ValueInt64(), 10))
	}
	if !data.ExportProtocol.IsNull() && !data.ExportProtocol.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"export-protocol", data.ExportProtocol.ValueString())
	}
	if !data.OptionInterfaceTableTimeout.IsNull() && !data.OptionInterfaceTableTimeout.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"option.interface-table.timeout", strconv.FormatInt(data.OptionInterfaceTableTimeout.ValueInt64(), 10))
	}
	if !data.OptionVrfTableTimeout.IsNull() && !data.OptionVrfTableTimeout.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"option.vrf-table.timeout", strconv.FormatInt(data.OptionVrfTableTimeout.ValueInt64(), 10))
	}
	if !data.OptionSamplerTable.IsNull() && !data.OptionSamplerTable.IsUnknown() {
		if data.OptionSamplerTable.ValueBool() {
			body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"option.sampler-table", map[string]string{})
		}
	}
	if !data.OptionApplicationTableTimeout.IsNull() && !data.OptionApplicationTableTimeout.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"option.application-table.timeout", strconv.FormatInt(data.OptionApplicationTableTimeout.ValueInt64(), 10))
	}
	if !data.OptionApplicationAttributesTimeout.IsNull() && !data.OptionApplicationAttributesTimeout.IsUnknown() {
		body, _ = sjson.Set(body, helpers.LastElement(data.getPath())+"."+"option.application-attributes.timeout", strconv.FormatInt(data.OptionApplicationAttributesTimeout.ValueInt64(), 10))
	}
	return body
}

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

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

func (data *FlowExporter) 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 + "name"); value.Exists() && !data.Name.IsNull() {
		data.Name = types.StringValue(value.String())
	} else {
		data.Name = types.StringNull()
	}
	if value := res.Get(prefix + "description"); value.Exists() && !data.Description.IsNull() {
		data.Description = types.StringValue(value.String())
	} else {
		data.Description = types.StringNull()
	}
	if value := res.Get(prefix + "destination.ipdest.ip"); value.Exists() && !data.DestinationIp.IsNull() {
		data.DestinationIp = types.StringValue(value.String())
	} else {
		data.DestinationIp = types.StringNull()
	}
	if value := res.Get(prefix + "source.Loopback"); value.Exists() && !data.SourceLoopback.IsNull() {
		data.SourceLoopback = types.Int64Value(value.Int())
	} else {
		data.SourceLoopback = types.Int64Null()
	}
	if value := res.Get(prefix + "transport.udp"); value.Exists() && !data.TransportUdp.IsNull() {
		data.TransportUdp = types.Int64Value(value.Int())
	} else {
		data.TransportUdp = types.Int64Null()
	}
	if value := res.Get(prefix + "template.data.timeout"); value.Exists() && !data.TemplateDataTimeout.IsNull() {
		data.TemplateDataTimeout = types.Int64Value(value.Int())
	} else {
		data.TemplateDataTimeout = types.Int64Null()
	}
	if value := res.Get(prefix + "export-protocol"); value.Exists() && !data.ExportProtocol.IsNull() {
		data.ExportProtocol = types.StringValue(value.String())
	} else {
		data.ExportProtocol = types.StringNull()
	}
	if value := res.Get(prefix + "option.interface-table.timeout"); value.Exists() && !data.OptionInterfaceTableTimeout.IsNull() {
		data.OptionInterfaceTableTimeout = types.Int64Value(value.Int())
	} else {
		data.OptionInterfaceTableTimeout = types.Int64Null()
	}
	if value := res.Get(prefix + "option.vrf-table.timeout"); value.Exists() && !data.OptionVrfTableTimeout.IsNull() {
		data.OptionVrfTableTimeout = types.Int64Value(value.Int())
	} else {
		data.OptionVrfTableTimeout = types.Int64Null()
	}
	if value := res.Get(prefix + "option.sampler-table"); !data.OptionSamplerTable.IsNull() {
		if value.Exists() {
			data.OptionSamplerTable = types.BoolValue(true)
		} else {
			data.OptionSamplerTable = types.BoolValue(false)
		}
	} else {
		data.OptionSamplerTable = types.BoolNull()
	}
	if value := res.Get(prefix + "option.application-table.timeout"); value.Exists() && !data.OptionApplicationTableTimeout.IsNull() {
		data.OptionApplicationTableTimeout = types.Int64Value(value.Int())
	} else {
		data.OptionApplicationTableTimeout = types.Int64Null()
	}
	if value := res.Get(prefix + "option.application-attributes.timeout"); value.Exists() && !data.OptionApplicationAttributesTimeout.IsNull() {
		data.OptionApplicationAttributesTimeout = types.Int64Value(value.Int())
	} else {
		data.OptionApplicationAttributesTimeout = types.Int64Null()
	}
}

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

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

func (data *FlowExporter) 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 + "description"); value.Exists() {
		data.Description = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "destination.ipdest.ip"); value.Exists() {
		data.DestinationIp = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "source.Loopback"); value.Exists() {
		data.SourceLoopback = types.Int64Value(value.Int())
	}
	if value := res.Get(prefix + "transport.udp"); value.Exists() {
		data.TransportUdp = types.Int64Value(value.Int())
	}
	if value := res.Get(prefix + "template.data.timeout"); value.Exists() {
		data.TemplateDataTimeout = types.Int64Value(value.Int())
	}
	if value := res.Get(prefix + "export-protocol"); value.Exists() {
		data.ExportProtocol = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "option.interface-table.timeout"); value.Exists() {
		data.OptionInterfaceTableTimeout = types.Int64Value(value.Int())
	}
	if value := res.Get(prefix + "option.vrf-table.timeout"); value.Exists() {
		data.OptionVrfTableTimeout = types.Int64Value(value.Int())
	}
	if value := res.Get(prefix + "option.sampler-table"); value.Exists() {
		data.OptionSamplerTable = types.BoolValue(true)
	} else {
		data.OptionSamplerTable = types.BoolValue(false)
	}
	if value := res.Get(prefix + "option.application-table.timeout"); value.Exists() {
		data.OptionApplicationTableTimeout = types.Int64Value(value.Int())
	}
	if value := res.Get(prefix + "option.application-attributes.timeout"); value.Exists() {
		data.OptionApplicationAttributesTimeout = types.Int64Value(value.Int())
	}
}

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

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

func (data *FlowExporterData) 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 + "description"); value.Exists() {
		data.Description = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "destination.ipdest.ip"); value.Exists() {
		data.DestinationIp = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "source.Loopback"); value.Exists() {
		data.SourceLoopback = types.Int64Value(value.Int())
	}
	if value := res.Get(prefix + "transport.udp"); value.Exists() {
		data.TransportUdp = types.Int64Value(value.Int())
	}
	if value := res.Get(prefix + "template.data.timeout"); value.Exists() {
		data.TemplateDataTimeout = types.Int64Value(value.Int())
	}
	if value := res.Get(prefix + "export-protocol"); value.Exists() {
		data.ExportProtocol = types.StringValue(value.String())
	}
	if value := res.Get(prefix + "option.interface-table.timeout"); value.Exists() {
		data.OptionInterfaceTableTimeout = types.Int64Value(value.Int())
	}
	if value := res.Get(prefix + "option.vrf-table.timeout"); value.Exists() {
		data.OptionVrfTableTimeout = types.Int64Value(value.Int())
	}
	if value := res.Get(prefix + "option.sampler-table"); value.Exists() {
		data.OptionSamplerTable = types.BoolValue(true)
	} else {
		data.OptionSamplerTable = types.BoolValue(false)
	}
	if value := res.Get(prefix + "option.application-table.timeout"); value.Exists() {
		data.OptionApplicationTableTimeout = types.Int64Value(value.Int())
	}
	if value := res.Get(prefix + "option.application-attributes.timeout"); value.Exists() {
		data.OptionApplicationAttributesTimeout = types.Int64Value(value.Int())
	}
}

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

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

func (data *FlowExporter) getDeletedItems(ctx context.Context, state FlowExporter) []string {
	deletedItems := make([]string, 0)
	if !state.OptionApplicationAttributesTimeout.IsNull() && data.OptionApplicationAttributesTimeout.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/option/application-attributes/timeout", state.getPath()))
	}
	if !state.OptionApplicationTableTimeout.IsNull() && data.OptionApplicationTableTimeout.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/option/application-table/timeout", state.getPath()))
	}
	if !state.OptionSamplerTable.IsNull() && data.OptionSamplerTable.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/option/sampler-table", state.getPath()))
	}
	if !state.OptionVrfTableTimeout.IsNull() && data.OptionVrfTableTimeout.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/option/vrf-table/timeout", state.getPath()))
	}
	if !state.OptionInterfaceTableTimeout.IsNull() && data.OptionInterfaceTableTimeout.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/option/interface-table/timeout", state.getPath()))
	}
	if !state.ExportProtocol.IsNull() && data.ExportProtocol.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/export-protocol", state.getPath()))
	}
	if !state.TemplateDataTimeout.IsNull() && data.TemplateDataTimeout.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/template/data/timeout", state.getPath()))
	}
	if !state.TransportUdp.IsNull() && data.TransportUdp.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/transport/udp", state.getPath()))
	}
	if !state.SourceLoopback.IsNull() && data.SourceLoopback.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/source/Loopback", state.getPath()))
	}
	if !state.DestinationIp.IsNull() && data.DestinationIp.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/destination/ipdest/ip", state.getPath()))
	}
	if !state.Description.IsNull() && data.Description.IsNull() {
		deletedItems = append(deletedItems, fmt.Sprintf("%v/description", state.getPath()))
	}

	return deletedItems
}

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

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

func (data *FlowExporter) getEmptyLeafsDelete(ctx context.Context) []string {
	emptyLeafsDelete := make([]string, 0)
	if !data.OptionSamplerTable.IsNull() && !data.OptionSamplerTable.ValueBool() {
		emptyLeafsDelete = append(emptyLeafsDelete, fmt.Sprintf("%v/option/sampler-table", data.getPath()))
	}

	return emptyLeafsDelete
}

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

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

func (data *FlowExporter) getDeletePaths(ctx context.Context) []string {
	var deletePaths []string
	if !data.OptionApplicationAttributesTimeout.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/option/application-attributes/timeout", data.getPath()))
	}
	if !data.OptionApplicationTableTimeout.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/option/application-table/timeout", data.getPath()))
	}
	if !data.OptionSamplerTable.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/option/sampler-table", data.getPath()))
	}
	if !data.OptionVrfTableTimeout.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/option/vrf-table/timeout", data.getPath()))
	}
	if !data.OptionInterfaceTableTimeout.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/option/interface-table/timeout", data.getPath()))
	}
	if !data.ExportProtocol.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/export-protocol", data.getPath()))
	}
	if !data.TemplateDataTimeout.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/template/data/timeout", data.getPath()))
	}
	if !data.TransportUdp.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/transport/udp", data.getPath()))
	}
	if !data.SourceLoopback.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/source/Loopback", data.getPath()))
	}
	if !data.DestinationIp.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/destination/ipdest/ip", data.getPath()))
	}
	if !data.Description.IsNull() {
		deletePaths = append(deletePaths, fmt.Sprintf("%v/description", data.getPath()))
	}

	return deletePaths
}

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