// 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              = &EEMDataSource{}
	_ datasource.DataSourceWithConfigure = &EEMDataSource{}
)

func NewEEMDataSource() datasource.DataSource {
	return &EEMDataSource{}
}

type EEMDataSource struct {
	data *IosxeProviderData
}

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

func (d *EEMDataSource) 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 EEM 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,
			},
			"environment_variables": schema.ListNestedAttribute{
				MarkdownDescription: "Set an Embedded Event Manager global environment variable",
				Computed:            true,
				NestedObject: schema.NestedAttributeObject{
					Attributes: map[string]schema.Attribute{
						"name": schema.StringAttribute{
							MarkdownDescription: "",
							Computed:            true,
						},
						"value": schema.StringAttribute{
							MarkdownDescription: "",
							Computed:            true,
						},
					},
				},
			},
			"session_cli_username": schema.StringAttribute{
				MarkdownDescription: "username",
				Computed:            true,
			},
			"session_cli_username_privilege": schema.Int64Attribute{
				MarkdownDescription: "Set user privilege level",
				Computed:            true,
			},
			"history_size_events": schema.Int64Attribute{
				MarkdownDescription: "Embedded Event Manager event history table size",
				Computed:            true,
			},
			"history_size_traps": schema.Int64Attribute{
				MarkdownDescription: "Embedded Event Manager trap history table size",
				Computed:            true,
			},
			"directory_user_policy": schema.StringAttribute{
				MarkdownDescription: "Embedded Event Manager user policy directory",
				Computed:            true,
			},
			"scheduler_applet_thread_class_default": schema.BoolAttribute{
				MarkdownDescription: "default scheduler thread class",
				Computed:            true,
			},
			"scheduler_applet_thread_class_number": schema.Int64Attribute{
				MarkdownDescription: "Number of concurrent execution threads",
				Computed:            true,
			},
			"detector_rpc_max_sessions": schema.Int64Attribute{
				MarkdownDescription: "Maximum number of RPC sessions",
				Computed:            true,
			},
			"detector_routing_bootup_delay": schema.Float64Attribute{
				MarkdownDescription: "bootup delay in seconds",
				Computed:            true,
			},
			"applets": schema.ListNestedAttribute{
				MarkdownDescription: "Register an Event Manager applet",
				Computed:            true,
				NestedObject: schema.NestedAttributeObject{
					Attributes: map[string]schema.Attribute{
						"name": schema.StringAttribute{
							MarkdownDescription: "Name of the Event Manager applet",
							Computed:            true,
						},
						"authorization": schema.StringAttribute{
							MarkdownDescription: "Specify an authorization type for the applet",
							Computed:            true,
						},
						"class": schema.StringAttribute{
							MarkdownDescription: "Specify a class for the applet",
							Computed:            true,
						},
						"description": schema.StringAttribute{
							MarkdownDescription: "Add or modify an applet description",
							Computed:            true,
						},
						"event_cli_pattern": schema.StringAttribute{
							MarkdownDescription: "CLI command pattern match",
							Computed:            true,
						},
						"event_cli_sync": schema.StringAttribute{
							MarkdownDescription: "CLI and EEM policy execution sync or async",
							Computed:            true,
						},
						"event_cli_skip": schema.StringAttribute{
							MarkdownDescription: "describes whether to skip CLI command execution",
							Computed:            true,
						},
						"actions": schema.ListNestedAttribute{
							MarkdownDescription: "Add or modify an action statement",
							Computed:            true,
							NestedObject: schema.NestedAttributeObject{
								Attributes: map[string]schema.Attribute{
									"name": schema.StringAttribute{
										MarkdownDescription: "Label",
										Computed:            true,
									},
									"cli_command": schema.StringAttribute{
										MarkdownDescription: "CLI command",
										Computed:            true,
									},
									"regexp_string_pattern": schema.StringAttribute{
										MarkdownDescription: "regular expression pattern",
										Computed:            true,
									},
									"regexp_string_input": schema.StringAttribute{
										MarkdownDescription: "input string",
										Computed:            true,
									},
									"regexp_string_match": schema.StringAttribute{
										MarkdownDescription: "match variable",
										Computed:            true,
									},
									"regexp_string_match1": schema.StringAttribute{
										MarkdownDescription: "subsequent match variable",
										Computed:            true,
									},
									"regexp_string_match2": schema.StringAttribute{
										MarkdownDescription: "subsequent match variable",
										Computed:            true,
									},
									"regexp_string_match3": schema.StringAttribute{
										MarkdownDescription: "subsequent match variable",
										Computed:            true,
									},
									"syslog_facility": schema.StringAttribute{
										MarkdownDescription: "Facility string",
										Computed:            true,
									},
									"syslog_msg": schema.StringAttribute{
										MarkdownDescription: "Syslog message",
										Computed:            true,
									},
									"syslog_priority": schema.StringAttribute{
										MarkdownDescription: "Priority of syslog message",
										Computed:            true,
									},
									"set_varname": schema.StringAttribute{
										MarkdownDescription: "Name of the variable of set conditional",
										Computed:            true,
									},
									"set_value": schema.StringAttribute{
										MarkdownDescription: "Value of the variable of set conditional",
										Computed:            true,
									},
									"if_string_op_1": schema.StringAttribute{
										MarkdownDescription: "",
										Computed:            true,
									},
									"if_keyword": schema.StringAttribute{
										MarkdownDescription: "",
										Computed:            true,
									},
									"if_string_op_2": schema.StringAttribute{
										MarkdownDescription: "",
										Computed:            true,
									},
									"if_goto": schema.StringAttribute{
										MarkdownDescription: "goto label",
										Computed:            true,
									},
									"elseif_operand1": schema.StringAttribute{
										MarkdownDescription: "First operand of else if conditional",
										Computed:            true,
									},
									"elseif_operation": schema.StringAttribute{
										MarkdownDescription: "Operation of else if conditional",
										Computed:            true,
									},
									"elseif_operand2": schema.StringAttribute{
										MarkdownDescription: "Second operand of else if conditional",
										Computed:            true,
									},
									"else": schema.BoolAttribute{
										MarkdownDescription: "else conditional",
										Computed:            true,
									},
									"while_operand1": schema.StringAttribute{
										MarkdownDescription: "First operand of while conditional",
										Computed:            true,
									},
									"while_operation": schema.StringAttribute{
										MarkdownDescription: "Operation of while conditional",
										Computed:            true,
									},
									"while_operand2": schema.StringAttribute{
										MarkdownDescription: "Second operand of while conditional",
										Computed:            true,
									},
									"break": schema.BoolAttribute{
										MarkdownDescription: "break conditional",
										Computed:            true,
									},
									"continue": schema.BoolAttribute{
										MarkdownDescription: "continue conditional",
										Computed:            true,
									},
									"increment_varname": schema.StringAttribute{
										MarkdownDescription: "Name of the variable of increment conditional",
										Computed:            true,
									},
									"increment_value": schema.StringAttribute{
										MarkdownDescription: "value of the variable of increment conditional",
										Computed:            true,
									},
									"decrement_varname": schema.StringAttribute{
										MarkdownDescription: "Name of the variable of decrement conditional",
										Computed:            true,
									},
									"decrement_value": schema.StringAttribute{
										MarkdownDescription: "Value of the variable of decrement conditional",
										Computed:            true,
									},
									"append_varname": schema.StringAttribute{
										MarkdownDescription: "Name of the variable of append conditional",
										Computed:            true,
									},
									"append_value": schema.StringAttribute{
										MarkdownDescription: "Value of the variable of append conditional",
										Computed:            true,
									},
									"divide_operand1": schema.StringAttribute{
										MarkdownDescription: "First operand of divide conditional",
										Computed:            true,
									},
									"divide_operand2": schema.StringAttribute{
										MarkdownDescription: "Second operand of divide conditional",
										Computed:            true,
									},
									"foreach_loopvar": schema.StringAttribute{
										MarkdownDescription: "Loop variable name of for each conditional",
										Computed:            true,
									},
									"foreach_iterator": schema.StringAttribute{
										MarkdownDescription: "String to iterate over",
										Computed:            true,
									},
									"foreach_delimiter": schema.StringAttribute{
										MarkdownDescription: "Delimiter string of for each conditional",
										Computed:            true,
									},
									"gets": schema.StringAttribute{
										MarkdownDescription: "gets conditional",
										Computed:            true,
									},
									"puts": schema.StringAttribute{
										MarkdownDescription: "displays data to active tty",
										Computed:            true,
									},
									"wait": schema.Int64Attribute{
										MarkdownDescription: "Wait for a specified amount of time",
										Computed:            true,
									},
									"end": schema.BoolAttribute{
										MarkdownDescription: "end conditional block",
										Computed:            true,
									},
									"exit": schema.BoolAttribute{
										MarkdownDescription: "Exit from applet run",
										Computed:            true,
									},
									"reload": schema.BoolAttribute{
										MarkdownDescription: "Reload system",
										Computed:            true,
									},
									"context_retrieve_key": schema.StringAttribute{
										MarkdownDescription: "key name",
										Computed:            true,
									},
									"context_retrieve_variable": schema.StringAttribute{
										MarkdownDescription: "variable name pattern",
										Computed:            true,
									},
									"context_save_key": schema.StringAttribute{
										MarkdownDescription: "key name",
										Computed:            true,
									},
									"context_save_variable": schema.StringAttribute{
										MarkdownDescription: "variable name pattern",
										Computed:            true,
									},
									"string_trim": schema.StringAttribute{
										MarkdownDescription: "trim characters from both ends of string",
										Computed:            true,
									},
									"info_type_snmp_trap_enterprise_oid": schema.StringAttribute{
										MarkdownDescription: "Enterprise oid",
										Computed:            true,
									},
									"info_type_snmp_trap_generic_trapnum": schema.Int64Attribute{
										MarkdownDescription: "Generic trap number",
										Computed:            true,
									},
									"info_type_snmp_trap_specific_trapnum": schema.Int64Attribute{
										MarkdownDescription: "Specific trap number",
										Computed:            true,
									},
									"info_type_snmp_trap_trap_oid": schema.StringAttribute{
										MarkdownDescription: "Trap oid",
										Computed:            true,
									},
									"info_type_snmp_trap_trap_var": schema.StringAttribute{
										MarkdownDescription: "Trap variable",
										Computed:            true,
									},
									"handle_error_type": schema.StringAttribute{
										MarkdownDescription: "Error handle type of handle-error conditional",
										Computed:            true,
									},
									"counter_name": schema.StringAttribute{
										MarkdownDescription: "Name of the counter",
										Computed:            true,
									},
									"counter_value": schema.Int64Attribute{
										MarkdownDescription: "Value used to modify the counter",
										Computed:            true,
									},
									"counter_op_dec": schema.BoolAttribute{
										MarkdownDescription: "Decrement the value of the counter by the given value",
										Computed:            true,
									},
									"counter_op_inc": schema.BoolAttribute{
										MarkdownDescription: "Increment the value of the counter by the given value",
										Computed:            true,
									},
									"counter_op_set": schema.BoolAttribute{
										MarkdownDescription: "Set the value of the counter by the given value",
										Computed:            true,
									},
									"counter_op_nop": schema.BoolAttribute{
										MarkdownDescription: "Read the value of the counter",
										Computed:            true,
									},
									"snmp_trap_intdata1": schema.Int64Attribute{
										MarkdownDescription: "SNMP integer data1",
										Computed:            true,
									},
									"snmp_trap_intdata2": schema.Int64Attribute{
										MarkdownDescription: "SNMP integer data2",
										Computed:            true,
									},
									"snmp_trap_strdata": schema.StringAttribute{
										MarkdownDescription: "SNMP trap string",
										Computed:            true,
									},
									"info_type_snmp_var": schema.StringAttribute{
										MarkdownDescription: "",
										Computed:            true,
									},
									"info_type_snmp_var_oid": schema.StringAttribute{
										MarkdownDescription: "SNMP object id",
										Computed:            true,
									},
									"info_type_snmp_var_oid_type": schema.StringAttribute{
										MarkdownDescription: "",
										Computed:            true,
									},
									"info_type_snmp_var_oid_type_value": schema.StringAttribute{
										MarkdownDescription: "",
										Computed:            true,
									},
									"string_trim_first_string_op_1": schema.StringAttribute{
										MarkdownDescription: "",
										Computed:            true,
									},
									"string_trim_first_string_op_2": schema.StringAttribute{
										MarkdownDescription: "",
										Computed:            true,
									},
								},
							},
						},
						"event_timer_watchdog_time": schema.Float64Attribute{
							MarkdownDescription: "Time period for watchdog / countdown / absolute timer",
							Computed:            true,
						},
						"event_timer_watchdog_name": schema.StringAttribute{
							MarkdownDescription: "Timer name string",
							Computed:            true,
						},
						"event_timer_watchdog_maxrun": schema.Float64Attribute{
							MarkdownDescription: "Maximum runtime of applet",
							Computed:            true,
						},
						"event_timer_watchdog_ratelimit": schema.Float64Attribute{
							MarkdownDescription: "seconds[.milliseconds] value",
							Computed:            true,
						},
						"event_timer_cron_entry": schema.StringAttribute{
							MarkdownDescription: "Cron entry for cron timer",
							Computed:            true,
						},
						"event_timer_cron_name": schema.StringAttribute{
							MarkdownDescription: "Timer name string",
							Computed:            true,
						},
						"event_timer_cron_maxrun": schema.Float64Attribute{
							MarkdownDescription: "Maximum runtime of applet",
							Computed:            true,
						},
						"event_timer_cron_ratelimit": schema.Float64Attribute{
							MarkdownDescription: "seconds[.milliseconds] value",
							Computed:            true,
						},
					},
				},
			},
		},
	}
}

func (d *EEMDataSource) 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 *EEMDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
	var config EEMData

	// 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 = EEMData{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
