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

	"github.com/hashicorp/terraform-plugin-framework/datasource"
	"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
	"github.com/hashicorp/terraform-plugin-framework/path"
	"github.com/hashicorp/terraform-plugin-framework/types"
	"github.com/hashicorp/terraform-plugin-log/tflog"
)

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

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

// Ensure the implementation satisfies the expected interfaces.
var (
	_ datasource.DataSource              = &RouteMapDataSource{}
	_ datasource.DataSourceWithConfigure = &RouteMapDataSource{}
)

func NewRouteMapDataSource() datasource.DataSource {
	return &RouteMapDataSource{}
}

type RouteMapDataSource struct {
	data *IosxeProviderData
}

func (d *RouteMapDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
	resp.TypeName = req.ProviderTypeName + "_route_map"
}

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

func (d *RouteMapDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, _ *datasource.ConfigureResponse) {
	if req.ProviderData == nil {
		return
	}

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

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

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

func (d *RouteMapDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
	var config RouteMapData

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

	tflog.Debug(ctx, fmt.Sprintf("%s: Beginning Read", config.getPath()))

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

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

		config.fromBody(ctx, res.Res)
	}

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

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

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

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