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

	"github.com/CiscoDevNet/terraform-provider-iosxe/internal/provider/helpers"
	"github.com/hashicorp/terraform-plugin-framework-validators/int64validator"
	"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
	"github.com/hashicorp/terraform-plugin-framework/path"
	"github.com/hashicorp/terraform-plugin-framework/resource"
	"github.com/hashicorp/terraform-plugin-framework/resource/schema"
	"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
	"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
	"github.com/hashicorp/terraform-plugin-framework/schema/validator"
	"github.com/hashicorp/terraform-plugin-framework/types"
	"github.com/hashicorp/terraform-plugin-log/tflog"
	"github.com/netascode/go-restconf"
)

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

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

// Ensure provider defined types fully satisfy framework interfaces
var (
	_ resource.Resource                = &RouteMapResource{}
	_ resource.ResourceWithImportState = &RouteMapResource{}
)

func NewRouteMapResource() resource.Resource {
	return &RouteMapResource{}
}

type RouteMapResource struct {
	data *IosxeProviderData
}

func (r *RouteMapResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
	resp.TypeName = req.ProviderTypeName + "_route_map"
}

func (r *RouteMapResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
	resp.Schema = schema.Schema{
		// This description is used by the documentation generator and the language server.
		MarkdownDescription: "This resource can manage the Route Map configuration.",

		Attributes: map[string]schema.Attribute{
			"device": schema.StringAttribute{
				MarkdownDescription: "A device name from the provider configuration.",
				Optional:            true,
			},
			"id": schema.StringAttribute{
				MarkdownDescription: "The path of the object.",
				Computed:            true,
				PlanModifiers: []planmodifier.String{
					stringplanmodifier.UseStateForUnknown(),
				},
			},
			"name": schema.StringAttribute{
				MarkdownDescription: helpers.NewAttributeDescription("WORD;;Route map tag").String,
				Required:            true,
				PlanModifiers: []planmodifier.String{
					stringplanmodifier.RequiresReplace(),
				},
			},
			"entries": schema.ListNestedAttribute{
				MarkdownDescription: helpers.NewAttributeDescription("Sequence to insert to/delete from existing route-map entry").String,
				Optional:            true,
				NestedObject: schema.NestedAttributeObject{
					Attributes: map[string]schema.Attribute{
						"seq": schema.Int64Attribute{
							MarkdownDescription: helpers.NewAttributeDescription("").AddIntegerRangeDescription(0, 65535).String,
							Required:            true,
							Validators: []validator.Int64{
								int64validator.Between(0, 65535),
							},
						},
						"operation": schema.StringAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Route map permit/deny set operations").AddStringEnumDescription("deny", "permit").String,
							Optional:            true,
							Validators: []validator.String{
								stringvalidator.OneOf("deny", "permit"),
							},
						},
						"description": schema.StringAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Route-map comment").String,
							Optional:            true,
						},
						"continue": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Continue on a different entry within the route-map").String,
							Optional:            true,
						},
						"continue_sequence_number": schema.Int64Attribute{
							MarkdownDescription: helpers.NewAttributeDescription("Route-map entry sequence number").AddIntegerRangeDescription(0, 65535).String,
							Optional:            true,
							Validators: []validator.Int64{
								int64validator.Between(0, 65535),
							},
						},
						"match_interfaces": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"match_ip_address_access_lists": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"match_ip_address_prefix_lists": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Match entries of prefix-lists").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"match_ip_next_hop_access_lists": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"match_ip_next_hop_prefix_lists": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Match entries of prefix-lists").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"match_ipv6_address_access_lists": schema.StringAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("IPv6 access-list name").String,
							Optional:            true,
							Validators: []validator.String{
								stringvalidator.RegexMatches(regexp.MustCompile(`[a-zA-Z].*`), ""),
							},
						},
						"match_ipv6_address_prefix_lists": schema.StringAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("IPv6 prefix-list name").String,
							Optional:            true,
						},
						"match_ipv6_next_hop_access_lists": schema.StringAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("IPv6 access-list name").String,
							Optional:            true,
							Validators: []validator.String{
								stringvalidator.RegexMatches(regexp.MustCompile(`[a-zA-Z].*`), ""),
							},
						},
						"match_ipv6_next_hop_prefix_lists": schema.StringAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("IPv6 prefix-list name").String,
							Optional:            true,
						},
						"match_route_type_external": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("external route (BGP, EIGRP and OSPF type 1/2)").String,
							Optional:            true,
						},
						"match_route_type_external_type_1": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("OSPF external type 1 route").String,
							Optional:            true,
						},
						"match_route_type_external_type_2": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("OSPF external type 2 route").String,
							Optional:            true,
						},
						"match_route_type_internal": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("internal route (including OSPF intra/inter area)").String,
							Optional:            true,
						},
						"match_route_type_level_1": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("IS-IS level-1 route").String,
							Optional:            true,
						},
						"match_route_type_level_2": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("IS-IS level-2 route").String,
							Optional:            true,
						},
						"match_route_type_local_legacy": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("locally generated route (OBSOLETE - please use route-map configuration in Cisco-IOS-XE-bgp.yang)").String,
							Optional:            true,
						},
						"match_route_type_local": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("locally generated route").String,
							Optional:            true,
						},
						"match_source_protocol_bgp": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Border Gateway Protocol (BGP)").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"match_source_protocol_connected": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Connected").String,
							Optional:            true,
						},
						"match_source_protocol_eigrp": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Border Gateway Protocol (BGP)").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"match_source_protocol_isis": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("ISO IS-IS").String,
							Optional:            true,
						},
						"match_source_protocol_lisp": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Locator ID Separation Protocol (LISP)").String,
							Optional:            true,
						},
						"match_source_protocol_ospf": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Open Shortest Path First (OSPF)").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"match_source_protocol_ospfv3": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("OSPFv3").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"match_source_protocol_rip": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Routing Information Protocol (RIP)").String,
							Optional:            true,
						},
						"match_source_protocol_static": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Static routes").String,
							Optional:            true,
						},
						"match_tags": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Tag value (DEPRECATED - please use tag-val)").String,
							ElementType:         types.Int64Type,
							Optional:            true,
						},
						"match_track": schema.Int64Attribute{
							MarkdownDescription: helpers.NewAttributeDescription("tracking object").AddIntegerRangeDescription(1, 1000).String,
							Optional:            true,
							Validators: []validator.Int64{
								int64validator.Between(1, 1000),
							},
						},
						"match_as_paths_legacy": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("AS path access-list (OBSOLETE - please use route-map configuration in Cisco-IOS-XE-bgp.yang)").String,
							ElementType:         types.Int64Type,
							Optional:            true,
						},
						"match_community_lists_legacy": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Named Access List (OBSOLETE- please use community-list in Cisco-IOS-XE-bgp.yang)").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"match_extcommunity_lists_legacy": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Named Access List (OBSOLETE- please use extcommunity-list in Cisco-IOS-XE-bgp.yang)").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"match_local_preferences_legacy": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("").String,
							ElementType:         types.Int64Type,
							Optional:            true,
						},
						"match_as_paths": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("AS path access-list").String,
							ElementType:         types.Int64Type,
							Optional:            true,
						},
						"match_community_lists": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Named Access List").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"match_community_list_exact_match": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Do exact matching of communities").String,
							Optional:            true,
						},
						"match_extcommunity_lists": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Named Access List").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"match_local_preferences": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("").String,
							ElementType:         types.Int64Type,
							Optional:            true,
						},
						"set_default_interfaces": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("SPAN source interface").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"set_global": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("").String,
							Optional:            true,
						},
						"set_interfaces": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Interface specific information").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"set_ip_address": schema.StringAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Specify prefix-list").String,
							Optional:            true,
						},
						"set_ip_default_global_next_hop_address": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"set_ip_default_next_hop_address": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"set_ip_global_next_hop_address": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"set_ip_next_hop_address": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("IP address of next hop").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"set_ip_next_hop_self": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Use self address (for BGP only)").String,
							Optional:            true,
						},
						"set_ip_qos_group": schema.Int64Attribute{
							MarkdownDescription: helpers.NewAttributeDescription("").AddIntegerRangeDescription(0, 99).String,
							Optional:            true,
							Validators: []validator.Int64{
								int64validator.Between(0, 99),
							},
						},
						"set_ipv6_address": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("IPv6 prefix-list").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"set_ipv6_default_global_next_hop": schema.StringAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Next hop along path").String,
							Optional:            true,
							Validators: []validator.String{
								stringvalidator.RegexMatches(regexp.MustCompile(`((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(%[\p{N}\p{L}]+)?`), ""),
								stringvalidator.RegexMatches(regexp.MustCompile(`(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)(%.+)?`), ""),
							},
						},
						"set_ipv6_default_next_hop": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Default next hop IPv6 address").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"set_ipv6_next_hop": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Next hop IPv6 address").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"set_level_1": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Import into a level-1 area").String,
							Optional:            true,
						},
						"set_level_1_2": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Import into level-1 and level-2").String,
							Optional:            true,
						},
						"set_level_2": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Import into level-2 sub-domain").String,
							Optional:            true,
						},
						"set_metric_change": schema.StringAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("+/-<metric>;;Add or subtract metric").String,
							Optional:            true,
							Validators: []validator.String{
								stringvalidator.RegexMatches(regexp.MustCompile(`(\+|-)\d{1,10}`), ""),
							},
						},
						"set_metric_value": schema.Int64Attribute{
							MarkdownDescription: helpers.NewAttributeDescription("Metric value or Bandwidth in Kbits per second").AddIntegerRangeDescription(0, 4294967295).String,
							Optional:            true,
							Validators: []validator.Int64{
								int64validator.Between(0, 4294967295),
							},
						},
						"set_metric_delay": schema.StringAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("EIGRP delay metric, in 10 microsecond units").String,
							Optional:            true,
							Validators: []validator.String{
								stringvalidator.RegexMatches(regexp.MustCompile(`(\+|-)?\d{1,10}`), ""),
							},
						},
						"set_metric_reliability": schema.Int64Attribute{
							MarkdownDescription: helpers.NewAttributeDescription("EIGRP reliability metric where 255 is 100% reliable").AddIntegerRangeDescription(0, 255).String,
							Optional:            true,
							Validators: []validator.Int64{
								int64validator.Between(0, 255),
							},
						},
						"set_metric_loading": schema.Int64Attribute{
							MarkdownDescription: helpers.NewAttributeDescription("EIGRP Effective bandwidth metric (Loading) where 255 is 100% loaded").AddIntegerRangeDescription(1, 255).String,
							Optional:            true,
							Validators: []validator.Int64{
								int64validator.Between(1, 255),
							},
						},
						"set_metric_mtu": schema.Int64Attribute{
							MarkdownDescription: helpers.NewAttributeDescription("EIGRP MTU of the path").AddIntegerRangeDescription(1, 4294967295).String,
							Optional:            true,
							Validators: []validator.Int64{
								int64validator.Between(1, 4294967295),
							},
						},
						"set_metric_type": schema.StringAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Type of metric for destination routing protocol").AddStringEnumDescription("external", "internal", "type-1", "type-2").String,
							Optional:            true,
							Validators: []validator.String{
								stringvalidator.OneOf("external", "internal", "type-1", "type-2"),
							},
						},
						"set_tag": schema.Int64Attribute{
							MarkdownDescription: helpers.NewAttributeDescription("Tag value (DEPRECATED - please use tag-val)").AddIntegerRangeDescription(0, 4294967295).String,
							Optional:            true,
							Validators: []validator.Int64{
								int64validator.Between(0, 4294967295),
							},
						},
						"set_vrf": schema.StringAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("VPN Routing/Forwarding instance name").String,
							Optional:            true,
						},
						"set_as_path_prepend_as_legacy": schema.StringAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("<1-65535>;;AS number (OBSOLETE - please use route-map configuration in Cisco-IOS-XE-bgp.yang)").String,
							Optional:            true,
						},
						"set_as_path_prepend_last_as_legacy": schema.Int64Attribute{
							MarkdownDescription: helpers.NewAttributeDescription("").AddIntegerRangeDescription(1, 10).String,
							Optional:            true,
							Validators: []validator.Int64{
								int64validator.Between(1, 10),
							},
						},
						"set_as_path_tag_legacy": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Set the tag as an AS-path attribute (OBSOLETE - please use route-map configuration in Cisco-IOS-XE-bgp.yang)").String,
							Optional:            true,
						},
						"set_community_none_legacy": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("No community attribute (OBSOLETE - please use route-map configuration in Cisco-IOS-XE-bgp.yang)").String,
							Optional:            true,
						},
						"set_communities_legacy": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"set_communities_additive_legacy": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("").String,
							Optional:            true,
						},
						"set_community_list_delete_legacy": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Delete matching communities (OBSOLETE - please use route-map configuration in Cisco-IOS-XE-bgp.yang)").String,
							Optional:            true,
						},
						"set_community_list_standard_legacy": schema.Int64Attribute{
							MarkdownDescription: helpers.NewAttributeDescription("").AddIntegerRangeDescription(1, 99).String,
							Optional:            true,
							Validators: []validator.Int64{
								int64validator.Between(1, 99),
							},
						},
						"set_community_list_expanded_legacy": schema.Int64Attribute{
							MarkdownDescription: helpers.NewAttributeDescription("").AddIntegerRangeDescription(100, 500).String,
							Optional:            true,
							Validators: []validator.Int64{
								int64validator.Between(100, 500),
							},
						},
						"set_community_list_name_legacy": schema.StringAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("").String,
							Optional:            true,
						},
						"set_extcomunity_rt_legacy": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"set_extcomunity_soo_legacy": schema.StringAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("").String,
							Optional:            true,
							Validators: []validator.String{
								stringvalidator.RegexMatches(regexp.MustCompile(`(([0-9]+\.[0-9]+)|([0-9]+)|((([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))):[0-9]+`), ""),
							},
						},
						"set_extcomunity_vpn_distinguisher_legacy": schema.StringAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("").String,
							Optional:            true,
							Validators: []validator.String{
								stringvalidator.RegexMatches(regexp.MustCompile(`(([0-9]+\.[0-9]+)|([0-9]+)|((([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))):[0-9]+`), ""),
							},
						},
						"set_local_preference_legacy": schema.Int64Attribute{
							MarkdownDescription: helpers.NewAttributeDescription("Preference value (OBSOLETE - please use route-map configuration in Cisco-IOS-XE-bgp.yang)").AddIntegerRangeDescription(0, 4294967295).String,
							Optional:            true,
							Validators: []validator.Int64{
								int64validator.Between(0, 4294967295),
							},
						},
						"set_weight_legacy": schema.Int64Attribute{
							MarkdownDescription: helpers.NewAttributeDescription("BGP weight for routing table (OBSOLETE - please use route-map configuration in Cisco-IOS-XE-bgp.yang)").AddIntegerRangeDescription(0, 65535).String,
							Optional:            true,
							Validators: []validator.Int64{
								int64validator.Between(0, 65535),
							},
						},
						"set_as_path_prepend_as": schema.StringAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("BGP AS number").String,
							Optional:            true,
							Validators: []validator.String{
								stringvalidator.RegexMatches(regexp.MustCompile(`([0-9]+|[0-9]*\.[0-9]+)(\s+([0-9]+|[0-9]*\.[0-9]+))*`), ""),
							},
						},
						"set_as_path_prepend_last_as": schema.Int64Attribute{
							MarkdownDescription: helpers.NewAttributeDescription("").AddIntegerRangeDescription(1, 10).String,
							Optional:            true,
							Validators: []validator.Int64{
								int64validator.Between(1, 10),
							},
						},
						"set_as_path_tag": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Set the tag as an AS-path attribute").String,
							Optional:            true,
						},
						"set_as_path_replace_any": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Replace each AS number in the AS-path with the local AS").String,
							Optional:            true,
						},
						"set_as_path_replace_as": schema.ListNestedAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("").String,
							Optional:            true,
							NestedObject: schema.NestedAttributeObject{
								Attributes: map[string]schema.Attribute{
									"as_number": schema.StringAttribute{
										MarkdownDescription: helpers.NewAttributeDescription("<1-65535>;;AS number").String,
										Required:            true,
									},
								},
							},
						},
						"set_community_none": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("No community attribute").String,
							Optional:            true,
						},
						"set_communities": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"set_communities_additive": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("").String,
							Optional:            true,
						},
						"set_community_list_delete": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("Delete matching communities").String,
							Optional:            true,
						},
						"set_community_list_standard": schema.Int64Attribute{
							MarkdownDescription: helpers.NewAttributeDescription("").AddIntegerRangeDescription(1, 99).String,
							Optional:            true,
							Validators: []validator.Int64{
								int64validator.Between(1, 99),
							},
						},
						"set_community_list_expanded": schema.Int64Attribute{
							MarkdownDescription: helpers.NewAttributeDescription("").AddIntegerRangeDescription(100, 500).String,
							Optional:            true,
							Validators: []validator.Int64{
								int64validator.Between(100, 500),
							},
						},
						"set_community_list_name": schema.StringAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("").String,
							Optional:            true,
						},
						"set_extcomunity_rt": schema.ListAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("").String,
							ElementType:         types.StringType,
							Optional:            true,
						},
						"set_extcomunity_soo": schema.StringAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("").String,
							Optional:            true,
							Validators: []validator.String{
								stringvalidator.RegexMatches(regexp.MustCompile(`(([0-9]+\.[0-9]+)|([0-9]+)|((([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))):[0-9]+`), ""),
							},
						},
						"set_extcomunity_vpn_distinguisher": schema.StringAttribute{
							MarkdownDescription: helpers.NewAttributeDescription(" VPN Distinguisher Extended Community").String,
							Optional:            true,
							Validators: []validator.String{
								stringvalidator.RegexMatches(regexp.MustCompile(`(([0-9]+\.[0-9]+)|([0-9]+)|((([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))):[0-9]+`), ""),
							},
						},
						"set_extcomunity_vpn_distinguisher_additive": schema.BoolAttribute{
							MarkdownDescription: helpers.NewAttributeDescription("").String,
							Optional:            true,
						},
						"set_local_preference": schema.Int64Attribute{
							MarkdownDescription: helpers.NewAttributeDescription("Preference value").AddIntegerRangeDescription(0, 4294967295).String,
							Optional:            true,
							Validators: []validator.Int64{
								int64validator.Between(0, 4294967295),
							},
						},
						"set_weight": schema.Int64Attribute{
							MarkdownDescription: helpers.NewAttributeDescription("BGP weight for routing table").AddIntegerRangeDescription(0, 65535).String,
							Optional:            true,
							Validators: []validator.Int64{
								int64validator.Between(0, 65535),
							},
						},
					},
				},
			},
		},
	}
}

func (r *RouteMapResource) Configure(_ context.Context, req resource.ConfigureRequest, _ *resource.ConfigureResponse) {
	if req.ProviderData == nil {
		return
	}

	r.data = req.ProviderData.(*IosxeProviderData)
}

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

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

func (r *RouteMapResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
	var plan RouteMap

	// Read plan
	diags := req.Plan.Get(ctx, &plan)
	resp.Diagnostics.Append(diags...)
	if resp.Diagnostics.HasError() {
		return
	}

	tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Create", plan.getPath()))

	device, ok := r.data.Devices[plan.Device.ValueString()]
	if !ok {
		resp.Diagnostics.AddAttributeError(path.Root("device"), "Invalid device", fmt.Sprintf("Device '%s' does not exist in provider configuration.", plan.Device.ValueString()))
		return
	}

	if device.Managed {
		// Create object
		body := plan.toBody(ctx)

		emptyLeafsDelete := plan.getEmptyLeafsDelete(ctx)
		tflog.Debug(ctx, fmt.Sprintf("List of empty leafs to delete: %+v", emptyLeafsDelete))

		if YangPatch {
			edits := []restconf.YangPatchEdit{restconf.NewYangPatchEdit("merge", plan.getPath(), restconf.Body{Str: body})}
			for _, i := range emptyLeafsDelete {
				edits = append(edits, restconf.NewYangPatchEdit("remove", i, restconf.Body{}))
			}
			_, err := device.Client.YangPatchData("", "1", "", edits)
			if err != nil {
				resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object, got error: %s", err))
				return
			}
		} else {
			res, err := device.Client.PatchData(plan.getPathShort(), body)
			if len(res.Errors.Error) > 0 && res.Errors.Error[0].ErrorMessage == "patch to a nonexistent resource" {
				_, err = device.Client.PutData(plan.getPath(), body)
			}
			if err != nil {
				resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (PATCH, %s), got error: %s", plan.getPathShort(), err))
				return
			}
			for _, i := range emptyLeafsDelete {
				res, err := device.Client.DeleteData(i)
				if err != nil && res.StatusCode != 404 {
					resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to delete object (%s), got error: %s", i, err))
					return
				}
			}
		}
	}

	plan.Id = types.StringValue(plan.getPath())

	tflog.Debug(ctx, fmt.Sprintf("%s: Create finished successfully", plan.getPath()))

	diags = resp.State.Set(ctx, &plan)
	resp.Diagnostics.Append(diags...)

	helpers.SetFlagImporting(ctx, false, resp.Private, &resp.Diagnostics)
}

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

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

func (r *RouteMapResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
	var state RouteMap

	// Read state
	diags := req.State.Get(ctx, &state)
	resp.Diagnostics.Append(diags...)
	if resp.Diagnostics.HasError() {
		return
	}

	tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Read", state.Id.ValueString()))

	device, ok := r.data.Devices[state.Device.ValueString()]
	if !ok {
		resp.Diagnostics.AddAttributeError(path.Root("device"), "Invalid device", fmt.Sprintf("Device '%s' does not exist in provider configuration.", state.Device.ValueString()))
		return
	}

	if device.Managed {
		res, err := device.Client.GetData(state.Id.ValueString())
		if res.StatusCode == 404 {
			state = RouteMap{Device: state.Device, Id: state.Id}
		} else {
			if err != nil {
				resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to retrieve object (%s), got error: %s", state.Id.ValueString(), err))
				return
			}

			imp, diags := helpers.IsFlagImporting(ctx, req)
			if resp.Diagnostics.Append(diags...); resp.Diagnostics.HasError() {
				return
			}

			// After `terraform import` we switch to a full read.
			if imp {
				state.fromBody(ctx, res.Res)
			} else {
				state.updateFromBody(ctx, res.Res)
			}
		}
	}

	tflog.Debug(ctx, fmt.Sprintf("%s: Read finished successfully", state.Id.ValueString()))

	diags = resp.State.Set(ctx, &state)
	resp.Diagnostics.Append(diags...)

	helpers.SetFlagImporting(ctx, false, resp.Private, &resp.Diagnostics)
}

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

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

func (r *RouteMapResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
	var plan, state RouteMap

	// Read plan
	diags := req.Plan.Get(ctx, &plan)
	resp.Diagnostics.Append(diags...)
	if resp.Diagnostics.HasError() {
		return
	}

	// Read state
	diags = req.State.Get(ctx, &state)
	resp.Diagnostics.Append(diags...)
	if resp.Diagnostics.HasError() {
		return
	}

	tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Update", plan.Id.ValueString()))

	device, ok := r.data.Devices[plan.Device.ValueString()]
	if !ok {
		resp.Diagnostics.AddAttributeError(path.Root("device"), "Invalid device", fmt.Sprintf("Device '%s' does not exist in provider configuration.", plan.Device.ValueString()))
		return
	}

	if device.Managed {
		body := plan.toBody(ctx)

		deletedItems := plan.getDeletedItems(ctx, state)
		tflog.Debug(ctx, fmt.Sprintf("Removed items to delete: %+v", deletedItems))

		emptyLeafsDelete := plan.getEmptyLeafsDelete(ctx)
		tflog.Debug(ctx, fmt.Sprintf("List of empty leafs to delete: %+v", emptyLeafsDelete))

		if YangPatch {
			var edits []restconf.YangPatchEdit
			for _, i := range deletedItems {
				edits = append(edits, restconf.NewYangPatchEdit("remove", i, restconf.Body{}))
			}
			edits = append(edits, restconf.NewYangPatchEdit("merge", plan.getPath(), restconf.Body{Str: body}))
			for _, i := range emptyLeafsDelete {
				edits = append(edits, restconf.NewYangPatchEdit("remove", i, restconf.Body{}))
			}
			_, err := device.Client.YangPatchData("", "1", "", edits)
			if err != nil {
				resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to update object, got error: %s", err))
				return
			}
		} else {
			for _, i := range deletedItems {
				res, err := device.Client.DeleteData(i)
				if err != nil && res.StatusCode != 404 {
					resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to delete object (%s), got error: %s", i, err))
					return
				}
			}
			res, err := device.Client.PatchData(plan.getPathShort(), body)
			if len(res.Errors.Error) > 0 && res.Errors.Error[0].ErrorMessage == "patch to a nonexistent resource" {
				_, err = device.Client.PutData(plan.getPath(), body)
			}
			if err != nil {
				resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to configure object (PATCH, %s), got error: %s", plan.getPathShort(), err))
				return
			}
			for _, i := range emptyLeafsDelete {
				res, err := device.Client.DeleteData(i)
				if err != nil && res.StatusCode != 404 {
					resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to delete object (%s), got error: %s", i, err))
					return
				}
			}
		}
	}

	tflog.Debug(ctx, fmt.Sprintf("%s: Update finished successfully", plan.Id.ValueString()))

	diags = resp.State.Set(ctx, &plan)
	resp.Diagnostics.Append(diags...)
}

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

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

func (r *RouteMapResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
	var state RouteMap

	// Read state
	diags := req.State.Get(ctx, &state)
	resp.Diagnostics.Append(diags...)
	if resp.Diagnostics.HasError() {
		return
	}

	tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Delete", state.Id.ValueString()))

	device, ok := r.data.Devices[state.Device.ValueString()]
	if !ok {
		resp.Diagnostics.AddAttributeError(path.Root("device"), "Invalid device", fmt.Sprintf("Device '%s' does not exist in provider configuration.", state.Device.ValueString()))
		return
	}

	if device.Managed {
		deleteMode := "all"

		if deleteMode == "all" {
			res, err := device.Client.DeleteData(state.Id.ValueString())
			if err != nil && res.StatusCode != 404 && res.StatusCode != 400 {
				resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to delete object (%s), got error: %s", state.Id.ValueString(), err))
				return
			}
		} else {
			deletePaths := state.getDeletePaths(ctx)
			tflog.Debug(ctx, fmt.Sprintf("Paths to delete: %+v", deletePaths))

			if YangPatch {
				edits := []restconf.YangPatchEdit{}
				for _, i := range deletePaths {
					edits = append(edits, restconf.NewYangPatchEdit("remove", i, restconf.Body{}))
				}
				_, err := device.Client.YangPatchData("", "1", "", edits)
				if err != nil {
					resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to delete object, got error: %s", err))
					return
				}
			} else {
				for _, i := range deletePaths {
					res, err := device.Client.DeleteData(i)
					if err != nil && res.StatusCode != 404 {
						resp.Diagnostics.AddWarning("Client Warning", fmt.Sprintf("Failed to delete object (%s), got error: %s", i, err))
					}
				}
			}
		}
	}

	tflog.Debug(ctx, fmt.Sprintf("%s: Delete finished successfully", state.Id.ValueString()))

	resp.State.RemoveResource(ctx)
}

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

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

func (r *RouteMapResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
	idParts := strings.Split(req.ID, ",")
	idParts = helpers.RemoveEmptyStrings(idParts)

	if len(idParts) != 1 && len(idParts) != 2 {
		expectedIdentifier := "Expected import identifier with format: '<name>'"
		expectedIdentifier += " or '<name>,<device>'"
		resp.Diagnostics.AddError(
			"Unexpected Import Identifier",
			fmt.Sprintf("%s. Got: %q", expectedIdentifier, req.ID),
		)
		return
	}
	resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("name"), idParts[0])...)
	if len(idParts) == 2 {
		resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("device"), idParts[len(idParts)-1])...)
	}

	// construct path for 'id' attribute
	var state RouteMap
	diags := resp.State.Get(ctx, &state)
	resp.Diagnostics.Append(diags...)
	if resp.Diagnostics.HasError() {
		return
	}
	resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("id"), state.getPath())...)

	helpers.SetFlagImporting(ctx, true, resp.Private, &resp.Diagnostics)
}

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