package logicalports

import (
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)

func logicalPortAddressesSchema() *schema.Schema {
	return &schema.Schema{
		Type:     schema.TypeList,
		Computed: true,
		Elem: &schema.Resource{
			Schema: map[string]*schema.Schema{
				"ip": {
					Type:     schema.TypeString,
					Computed: true,
				},
				"ip_type": {
					Type:     schema.TypeString,
					Computed: true,
				},
				"mac": {
					Type:     schema.TypeString,
					Computed: true,
				},
				"id": {
					Type:     schema.TypeString,
					Computed: true,
				},
				"logical_port_id": {
					Type:     schema.TypeString,
					Computed: true,
				},
				"assigned_at": {
					Type:     schema.TypeString,
					Computed: true,
				},
				"is_discovered": {
					Type:     schema.TypeBool,
					Computed: true,
				},
				"is_primary": {
					Type:     schema.TypeBool,
					Computed: true,
				},
			},
		},
	}
}

func resourceLogicalPortSchemaMake() map[string]*schema.Schema {
	res := map[string]*schema.Schema{
		"access_group_id": {
			Type:        schema.TypeString,
			Required:    true,
			Description: "Access Group ID",
		},
		"description": {
			Type:        schema.TypeString,
			Required:    true,
			Description: "Description",
		},
		"display_name": {
			Type:        schema.TypeString,
			Required:    true,
			Description: "Display Name",
		},
		"enabled": {
			Type:        schema.TypeBool,
			Required:    true,
			Description: "Whether the logical port should be enabled",
		},
		"hypervisor": {
			Type:        schema.TypeString,
			Required:    true,
			Description: "Hypervisor",
		},
		"port_security": {
			Type:        schema.TypeBool,
			Required:    true,
			Description: "Whether the port security is enabled",
		},
		"segment_id": {
			Type:        schema.TypeString,
			Required:    true,
			Description: "Segment ID",
		},
		"adapter_mac": {
			Type:        schema.TypeString,
			Optional:    true,
			Computed:    true,
			Description: "Adapter MAC address",
		},
		"unique_identifier": {
			Type:        schema.TypeString,
			Optional:    true,
			Description: "Unique identifier of the logical port",
		},
		"force": {
			Type:     schema.TypeBool,
			Optional: true,
			Default:  false,
		},
		"migrate": {
			Type:        schema.TypeBool,
			Optional:    true,
			Default:     false,
			Description: "If true, triggers live migration to the hypervisor specified in the 'hypervisor' field. If false, hypervisor changes are applied via the regular update endpoint.",
		},
		"logical_port_addresses": {
			Type:     schema.TypeList,
			Optional: true,
			Elem: &schema.Resource{
				Schema: map[string]*schema.Schema{
					"ip": {
						Type:        schema.TypeString,
						Required:    true,
						Description: "IP address of the logical port",
					},
					"ip_type": {
						Type:         schema.TypeString,
						Required:     true,
						ValidateFunc: validation.StringInSlice([]string{"IPv4", "IPv6"}, false),
					},
					"is_primary": {
						Type:     schema.TypeBool,
						Required: true,
					},
					"is_discovered": {
						Type:     schema.TypeBool,
						Optional: true,
						Default:  false,
					},
					"mac": {
						Type:     schema.TypeString,
						Optional: true,
					},
				},
			},
		},
		"id": {
			Type:        schema.TypeString,
			Computed:    true,
			Description: "ID of the logical port",
		},
		"access_group_name": {
			Type:        schema.TypeString,
			Computed:    true,
			Description: "Name of the access group",
		},
		"address_detection": {
			Type:     schema.TypeBool,
			Computed: true,
		},
		"created_at": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"external_network_id": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"hypervisor_display_name": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"live_migration_target_hv": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"status": {
			Type:     schema.TypeList,
			Computed: true,
			Elem: &schema.Resource{
				Schema: map[string]*schema.Schema{
					"operation_status": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Operation status",
					},
					"hypervisor_status": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Hypervisor status",
					},
					"hypervisors": {
						Type:     schema.TypeList,
						Computed: true,
						Elem: &schema.Resource{
							Schema: map[string]*schema.Schema{
								"operation_status": {
									Type:        schema.TypeString,
									Computed:    true,
									Description: "Operation status of the hypervisor",
								},
								"name": {
									Type:        schema.TypeString,
									Computed:    true,
									Description: "Name of the hypervisor",
								},
								"display_name": {
									Type:        schema.TypeString,
									Computed:    true,
									Description: "Display name of the hypervisor",
								},
								"hypervisor_status": {
									Type:        schema.TypeString,
									Computed:    true,
									Description: "Status of the hypervisor",
								},
								"synced_at": {
									Type:        schema.TypeString,
									Computed:    true,
									Description: "Sync time of the hypervisor",
								},
							},
						},
					},
				},
			},
		},
		"bindings": {
			Type:     schema.TypeList,
			Computed: true,
			Elem: &schema.Resource{
				Schema: map[string]*schema.Schema{
					"id": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Unique identifier of the binding",
					},
					"segment_id": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Unique identifier of the segment",
					},
					"segment_display_name": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Display name of the segment",
					},
					"port_security": {
						Type:        schema.TypeBool,
						Computed:    true,
						Description: "If the port is secured",
					},
					"address_detection": {
						Type:        schema.TypeBool,
						Computed:    true,
						Description: "If the adapter address detection is enabled",
					},
					"version_id": {
						Type:        schema.TypeInt,
						Computed:    true,
						Description: "Version ID of the binding",
					},
					"created_at": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Creation time of the binding",
					},
					"updated_at": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Update time of the binding",
					},
					"logical_port_addresses": logicalPortAddressesSchema(),
				},
			},
		},
		"version_id": {
			Type:        schema.TypeInt,
			Computed:    true,
			Description: "Version ID of the logical port",
		},
		"labels": {
			Type:     schema.TypeList,
			Optional: true,
			Computed: true,
			MaxItems: 1,
			Elem: &schema.Resource{
				Schema: map[string]*schema.Schema{
					"vm_id": {
						Type:        schema.TypeString,
						Optional:    true,
						Computed:    true,
						Description: "VM ID label",
					},
					"vm_name": {
						Type:        schema.TypeString,
						Optional:    true,
						Computed:    true,
						Description: "VM name label",
					},
				},
			},
			Description: "Labels",
		},
	}
	return res
}

func dataSourceLogicalPortListSchemaMake() map[string]*schema.Schema {
	res := map[string]*schema.Schema{
		"access_group_id": {
			Type:        schema.TypeString,
			Optional:    true,
			Description: "Access Group ID",
		},
		"segment_id": {
			Type:        schema.TypeString,
			Optional:    true,
			Description: "Segment ID",
		},
		"segment_display_name": {
			Type:        schema.TypeString,
			Optional:    true,
			Description: "Segment display name",
		},
		"external_network_id": {
			Type:        schema.TypeString,
			Optional:    true,
			Description: "External Network ID",
		},
		"unique_identifier": {
			Type:        schema.TypeString,
			Optional:    true,
			Description: "Unique identifier",
		},
		"display_name": {
			Type:        schema.TypeString,
			Optional:    true,
			Description: "Display name",
		},
		"adapter_mac": {
			Type:        schema.TypeString,
			Optional:    true,
			Description: "Adapter mac",
		},
		"hypervisor": {
			Type:        schema.TypeString,
			Optional:    true,
			Description: "Hypervisor",
		},
		"hypervisor_display_name": {
			Type:        schema.TypeString,
			Optional:    true,
			Description: "Hypervisor display name",
		},
		"live_migration_target_hv": {
			Type:        schema.TypeString,
			Optional:    true,
			Description: "Live migration target HV",
		},
		"port_security": {
			Type:     schema.TypeBool,
			Optional: true,
		},
		"address_detection": {
			Type:     schema.TypeBool,
			Optional: true,
		},
		"enabled": {
			Type:     schema.TypeBool,
			Optional: true,
		},
		"created_from": {
			Type:     schema.TypeString,
			Optional: true,
		},
		"created_to": {
			Type:     schema.TypeString,
			Optional: true,
		},
		"page": {
			Type:     schema.TypeInt,
			Optional: true,
		},
		"per_page": {
			Type:     schema.TypeInt,
			Optional: true,
		},
		"sort_by": {
			Type:     schema.TypeString,
			Optional: true,
			ValidateFunc: validation.StringInSlice([]string{"display_name", "created_at", "updated_at",
				"deleted_at", "segment_id", "hypervisor",
				"port_security", "segment_display_name", "primary_address",
				"hypervisor_display_name"}, false),
		},
		"sort_order": {
			Type:         schema.TypeString,
			Optional:     true,
			ValidateFunc: validation.StringInSlice([]string{"asc", "dec"}, false),
		},
		"operation_status": {
			Type:     schema.TypeString,
			Optional: true,
			ValidateFunc: validation.StringInSlice([]string{
				"Idle", "SynchronizingAtCore", "SynchronizingAtOVN",
				"Synchronized", "NoHypervisorAtOVN", "FailedAtCore", "TemporaryFailedAtCore",
			}, false),
			Description: "Filter by operation status",
		},
		"hypervisor_status": {
			Type:         schema.TypeString,
			Optional:     true,
			ValidateFunc: validation.StringInSlice([]string{"Up", "Warning", "Error"}, false),
			Description:  "Filter by hypervisor status",
		},
		"items": {
			Type:     schema.TypeList,
			Computed: true,
			Elem: &schema.Resource{
				Schema: map[string]*schema.Schema{
					"id": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "ID of the logical port to use",
					},
					"access_group_id": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "ID of the access group",
					},
					"access_group_name": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Name of the access group",
					},
					"adapter_mac": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "MAC address of the adapter",
					},
					"address_detection": {
						Type:        schema.TypeBool,
						Computed:    true,
						Description: "If the adapter address detection is enabled",
					},
					"description": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Description of the logical port",
					},
					"display_name": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Display name of the logical port",
					},
					"enabled": {
						Type:        schema.TypeBool,
						Computed:    true,
						Description: "If the logical port is enabled",
					},
					"hypervisor": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "ID of the hypervisor",
					},
					"hypervisor_display_name": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Display name of the hypervisor",
					},
					"external_network_id": {
						Type:     schema.TypeString,
						Computed: true,
					},
					"live_migration_target_hv": {
						Type:     schema.TypeString,
						Computed: true,
					},
					"status": {
						Type:     schema.TypeList,
						Computed: true,
						Elem: &schema.Resource{
							Schema: map[string]*schema.Schema{
								"operation_status": {
									Type:        schema.TypeString,
									Computed:    true,
									Description: "Operation status",
								},
								"hypervisor_status": {
									Type:        schema.TypeString,
									Computed:    true,
									Description: "Hypervisor status",
								},
								"hypervisors": {
									Type:     schema.TypeList,
									Computed: true,
									Elem: &schema.Resource{
										Schema: map[string]*schema.Schema{
											"operation_status": {
												Type:        schema.TypeString,
												Computed:    true,
												Description: "Operation status of the hypervisor",
											},
											"name": {
												Type:        schema.TypeString,
												Computed:    true,
												Description: "Name of the hypervisor",
											},
											"display_name": {
												Type:        schema.TypeString,
												Computed:    true,
												Description: "Display name of the hypervisor",
											},
											"hypervisor_status": {
												Type:        schema.TypeString,
												Computed:    true,
												Description: "Status of the hypervisor",
											},
											"synced_at": {
												Type:        schema.TypeString,
												Computed:    true,
												Description: "Sync time of the hypervisor",
											},
										},
									},
								},
							},
						},
					},
					"unique_identifier": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Unique identifier of the logical port",
					},
					"version_id": {
						Type:        schema.TypeInt,
						Computed:    true,
						Description: "Version ID of the logical port",
					},
					"bindings": {
						Type:     schema.TypeList,
						Computed: true,
						Elem: &schema.Resource{
							Schema: map[string]*schema.Schema{
								"id": {
									Type:        schema.TypeString,
									Computed:    true,
									Description: "Unique identifier of the binding",
								},
								"segment_id": {
									Type:        schema.TypeString,
									Computed:    true,
									Description: "Unique identifier of the segment",
								},
								"segment_display_name": {
									Type:        schema.TypeString,
									Computed:    true,
									Description: "Display name of the segment",
								},
								"port_security": {
									Type:        schema.TypeBool,
									Computed:    true,
									Description: "If the port is secured",
								},
								"address_detection": {
									Type:        schema.TypeBool,
									Computed:    true,
									Description: "If the adapter address detection is enabled",
								},
								"version_id": {
									Type:        schema.TypeInt,
									Computed:    true,
									Description: "Version ID of the binding",
								},
								"created_at": {
									Type:        schema.TypeString,
									Computed:    true,
									Description: "Creation time of the binding",
								},
								"updated_at": {
									Type:        schema.TypeString,
									Computed:    true,
									Description: "Update time of the binding",
								},
								"logical_port_addresses": logicalPortAddressesSchema(),
							},
						},
					},
					"created_at": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Creation time of the logical port",
					},
					"updated_at": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Update time the logical port",
					},
					"labels": {
						Type:     schema.TypeList,
						Computed: true,
						Elem: &schema.Resource{
							Schema: map[string]*schema.Schema{
								"vm_id": {
									Type:        schema.TypeString,
									Computed:    true,
									Description: "VM ID label",
								},
								"vm_name": {
									Type:        schema.TypeString,
									Computed:    true,
									Description: "VM name label",
								},
							},
						},
						Description: "Labels",
					},
				},
			},
		},
	}
	return res
}

func dataSourceLogicalPortByUniqueIDSchemaMake() map[string]*schema.Schema {
	res := map[string]*schema.Schema{
		"unique_identifier": {
			Type:        schema.TypeString,
			Required:    true,
			Description: "Unique ID of the logical port to use",
		},
		"access_group_id": {
			Type:        schema.TypeString,
			Computed:    true,
			Description: "ID of the access group",
		},
		"access_group_name": {
			Type:        schema.TypeString,
			Computed:    true,
			Description: "Name of the access group",
		},
		"adapter_mac": {
			Type:        schema.TypeString,
			Computed:    true,
			Description: "MAC address of the adapter",
		},
		"address_detection": {
			Type:        schema.TypeBool,
			Computed:    true,
			Description: "If the adapter address detection is enabled",
		},
		"description": {
			Type:        schema.TypeString,
			Computed:    true,
			Description: "Description of the logical port",
		},
		"display_name": {
			Type:        schema.TypeString,
			Computed:    true,
			Description: "Display name of the logical port",
		},
		"enabled": {
			Type:        schema.TypeBool,
			Computed:    true,
			Description: "If the logical port is enabled",
		},
		"hypervisor": {
			Type:        schema.TypeString,
			Computed:    true,
			Description: "ID of the hypervisor",
		},
		"hypervisor_display_name": {
			Type:        schema.TypeString,
			Computed:    true,
			Description: "Display name of the hypervisor",
		},
		"external_network_id": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"live_migration_target_hv": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"status": {
			Type:     schema.TypeList,
			Computed: true,
			Elem: &schema.Resource{
				Schema: map[string]*schema.Schema{
					"operation_status": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Operation status",
					},
					"hypervisor_status": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Hypervisor status",
					},
					"hypervisors": {
						Type:     schema.TypeList,
						Computed: true,
						Elem: &schema.Resource{
							Schema: map[string]*schema.Schema{
								"operation_status": {
									Type:        schema.TypeString,
									Computed:    true,
									Description: "Operation status of the hypervisor",
								},
								"name": {
									Type:        schema.TypeString,
									Computed:    true,
									Description: "Name of the hypervisor",
								},
								"display_name": {
									Type:        schema.TypeString,
									Computed:    true,
									Description: "Display name of the hypervisor",
								},
								"hypervisor_status": {
									Type:        schema.TypeString,
									Computed:    true,
									Description: "Status of the hypervisor",
								},
								"synced_at": {
									Type:        schema.TypeString,
									Computed:    true,
									Description: "Sync time of the hypervisor",
								},
							},
						},
					},
				},
			},
		},
		"version_id": {
			Type:        schema.TypeInt,
			Computed:    true,
			Description: "Version ID of the logical port",
		},
		"bindings": {
			Type:     schema.TypeList,
			Computed: true,
			Elem: &schema.Resource{
				Schema: map[string]*schema.Schema{
					"id": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Unique identifier of the binding",
					},
					"segment_id": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Unique identifier of the segment",
					},
					"segment_display_name": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Display name of the segment",
					},
					"port_security": {
						Type:        schema.TypeBool,
						Computed:    true,
						Description: "If the port is secured",
					},
					"address_detection": {
						Type:        schema.TypeBool,
						Computed:    true,
						Description: "If the adapter address detection is enabled",
					},
					"version_id": {
						Type:        schema.TypeInt,
						Computed:    true,
						Description: "Version ID of the binding",
					},
					"created_at": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Creation time of the binding",
					},
					"updated_at": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Update time of the binding",
					},
					"logical_port_addresses": logicalPortAddressesSchema(),
				},
			},
		},
		"created_at": {
			Type:        schema.TypeString,
			Computed:    true,
			Description: "Creation time of the logical port",
		},
		"updated_at": {
			Type:        schema.TypeString,
			Computed:    true,
			Description: "Update time the logical port",
		},
		"labels": {
			Type:     schema.TypeList,
			Computed: true,
			Elem: &schema.Resource{
				Schema: map[string]*schema.Schema{
					"vm_id": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "VM ID label",
					},
					"vm_name": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "VM name label",
					},
				},
			},
			Description: "Labels",
		},
	}
	return res
}

func dataSourceLogicalPortSchemaMake() map[string]*schema.Schema {
	res := map[string]*schema.Schema{
		"logical_port_id": {
			Type:        schema.TypeString,
			Required:    true,
			Description: "ID of the logical port to use",
		},
		"access_group_id": {
			Type:        schema.TypeString,
			Computed:    true,
			Description: "ID of the access group",
		},
		"access_group_name": {
			Type:        schema.TypeString,
			Computed:    true,
			Description: "Name of the access group",
		},
		"adapter_mac": {
			Type:        schema.TypeString,
			Computed:    true,
			Description: "MAC address of the adapter",
		},
		"address_detection": {
			Type:        schema.TypeBool,
			Computed:    true,
			Description: "If the adapter address detection is enabled",
		},
		"description": {
			Type:        schema.TypeString,
			Computed:    true,
			Description: "Description of the logical port",
		},
		"display_name": {
			Type:        schema.TypeString,
			Computed:    true,
			Description: "Display name of the logical port",
		},
		"enabled": {
			Type:        schema.TypeBool,
			Computed:    true,
			Description: "If the logical port is enabled",
		},
		"hypervisor": {
			Type:        schema.TypeString,
			Computed:    true,
			Description: "ID of the hypervisor",
		},
		"hypervisor_display_name": {
			Type:        schema.TypeString,
			Computed:    true,
			Description: "Display name of the hypervisor",
		},
		"external_network_id": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"live_migration_target_hv": {
			Type:     schema.TypeString,
			Computed: true,
		},
		"status": {
			Type:     schema.TypeList,
			Computed: true,
			Elem: &schema.Resource{
				Schema: map[string]*schema.Schema{
					"operation_status": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Operation status",
					},
					"hypervisor_status": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Hypervisor status",
					},
					"hypervisors": {
						Type:     schema.TypeList,
						Computed: true,
						Elem: &schema.Resource{
							Schema: map[string]*schema.Schema{
								"operation_status": {
									Type:        schema.TypeString,
									Computed:    true,
									Description: "Operation status of the hypervisor",
								},
								"name": {
									Type:        schema.TypeString,
									Computed:    true,
									Description: "Name of the hypervisor",
								},
								"display_name": {
									Type:        schema.TypeString,
									Computed:    true,
									Description: "Display name of the hypervisor",
								},
								"hypervisor_status": {
									Type:        schema.TypeString,
									Computed:    true,
									Description: "Status of the hypervisor",
								},
								"synced_at": {
									Type:        schema.TypeString,
									Computed:    true,
									Description: "Sync time of the hypervisor",
								},
							},
						},
					},
				},
			},
		},
		"unique_identifier": {
			Type:        schema.TypeString,
			Computed:    true,
			Description: "Unique identifier of the logical port",
		},
		"version_id": {
			Type:        schema.TypeInt,
			Computed:    true,
			Description: "Version ID of the logical port",
		},
		"bindings": {
			Type:     schema.TypeList,
			Computed: true,
			Elem: &schema.Resource{
				Schema: map[string]*schema.Schema{
					"id": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Unique identifier of the binding",
					},
					"segment_id": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Unique identifier of the segment",
					},
					"segment_display_name": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Display name of the segment",
					},
					"port_security": {
						Type:        schema.TypeBool,
						Computed:    true,
						Description: "If the port is secured",
					},
					"address_detection": {
						Type:        schema.TypeBool,
						Computed:    true,
						Description: "If the adapter address detection is enabled",
					},
					"version_id": {
						Type:        schema.TypeInt,
						Computed:    true,
						Description: "Version ID of the binding",
					},
					"created_at": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Creation time of the binding",
					},
					"updated_at": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "Update time of the binding",
					},
					"logical_port_addresses": logicalPortAddressesSchema(),
				},
			},
		},
		"created_at": {
			Type:        schema.TypeString,
			Computed:    true,
			Description: "Creation time of the logical port",
		},
		"updated_at": {
			Type:        schema.TypeString,
			Computed:    true,
			Description: "Update time the logical port",
		},
		"labels": {
			Type:     schema.TypeList,
			Computed: true,
			Elem: &schema.Resource{
				Schema: map[string]*schema.Schema{
					"vm_id": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "VM ID label",
					},
					"vm_name": {
						Type:        schema.TypeString,
						Computed:    true,
						Description: "VM name label",
					},
				},
			},
			Description: "Labels",
		},
	}
	return res
}
