package models

import (
	"github.com/hashicorp/terraform-plugin-framework-timeouts/datasource/timeouts"
	"github.com/hashicorp/terraform-plugin-framework/attr"
	"github.com/hashicorp/terraform-plugin-framework/types"
)

// models

type DataSourceVINSModel struct {
	// request fields
	VinsID   types.Int64    `tfsdk:"vins_id"`
	Timeouts timeouts.Value `tfsdk:"timeouts"`

	// response fields
	Id                 types.String `tfsdk:"id"`
	VNFDev             types.Object `tfsdk:"vnf_dev"`
	AccountID          types.Int64  `tfsdk:"account_id"`
	AccountName        types.String `tfsdk:"account_name"`
	Computes           types.List   `tfsdk:"computes"`
	CreatedBy          types.String `tfsdk:"created_by"`
	CreatedTime        types.Int64  `tfsdk:"created_time"`
	DefaultGW          types.String `tfsdk:"default_gw"`
	DefaultQOS         types.Object `tfsdk:"default_qos"`
	DeletedBy          types.String `tfsdk:"deleted_by"`
	DeletedTime        types.Int64  `tfsdk:"deleted_time"`
	Description        types.String `tfsdk:"desc"`
	GID                types.Int64  `tfsdk:"gid"`
	GUID               types.Int64  `tfsdk:"guid"`
	LockStatus         types.String `tfsdk:"lock_status"`
	ManagerID          types.Int64  `tfsdk:"manager_id"`
	ManagerType        types.String `tfsdk:"manager_type"`
	Milestones         types.Int64  `tfsdk:"milestones"`
	Name               types.String `tfsdk:"name"`
	NetMask            types.Int64  `tfsdk:"net_mask"`
	Network            types.String `tfsdk:"network"`
	PreReservationsNum types.Int64  `tfsdk:"pre_reservations_num"`
	Redundant          types.Bool   `tfsdk:"redundant"`
	RGID               types.Int64  `tfsdk:"rg_id"`
	RGName             types.String `tfsdk:"rg_name"`
	SecVNFDevID        types.Int64  `tfsdk:"sec_vnf_dev_id"`
	Status             types.String `tfsdk:"status"`
	UpdatedBy          types.String `tfsdk:"updated_by"`
	UpdatedTime        types.Int64  `tfsdk:"updated_time"`
	UserManaged        types.Bool   `tfsdk:"user_managed"`
	VNFs               types.Object `tfsdk:"vnfs"`
	VXLANID            types.Int64  `tfsdk:"vxlan_id"`
}

type RecordVNFDevModel struct {
	CKey            types.String `tfsdk:"ckey"`
	AccountID       types.Int64  `tfsdk:"account_id"`
	Capabilities    types.List   `tfsdk:"capabilities"`
	Config          types.Object `tfsdk:"config"`
	ConfigSaved     types.Bool   `tfsdk:"config_saved"`
	CustomPreConfig types.Bool   `tfsdk:"custom_pre_cfg"`
	Description     types.String `tfsdk:"desc"`
	GID             types.Int64  `tfsdk:"gid"`
	GUID            types.Int64  `tfsdk:"guid"`
	VNFID           types.Int64  `tfsdk:"vnf_id"`
	Interfaces      types.List   `tfsdk:"interfaces"`
	LockStatus      types.String `tfsdk:"lock_status"`
	Milestones      types.Int64  `tfsdk:"milestones"`
	VNFName         types.String `tfsdk:"vnf_name"`
	Status          types.String `tfsdk:"status"`
	TechStatus      types.String `tfsdk:"tech_status"`
	Type            types.String `tfsdk:"type"`
	VNCPassword     types.String `tfsdk:"vnc_password"`
	VINS            types.List   `tfsdk:"vins"`
}

type RecordVNFConfigModel struct {
	MGMT      types.Object `tfsdk:"mgmt"`
	Resources types.Object `tfsdk:"resources"`
}

type RecordMGMTModel struct {
	IPAddress types.String `tfsdk:"ip_addr"`
	Password  types.String `tfsdk:"password"`
	SSHKey    types.String `tfsdk:"ssh_key"`
	User      types.String `tfsdk:"user"`
}

type RecordResourcesModel struct {
	CPU     types.Int64  `tfsdk:"cpu"`
	RAM     types.Int64  `tfsdk:"ram"`
	StackID types.Int64  `tfsdk:"stack_id"`
	UUID    types.String `tfsdk:"uuid"`
}

type VNFInterfaceModel struct {
	BusNumber       types.Int64  `tfsdk:"bus_number"`
	ConnID          types.Int64  `tfsdk:"conn_id"`
	ConnType        types.String `tfsdk:"conn_type"`
	DefGW           types.String `tfsdk:"def_gw"`
	Enabled         types.Bool   `tfsdk:"enabled"`
	FLIPGroupID     types.Int64  `tfsdk:"flipgroup_id"`
	GUID            types.String `tfsdk:"guid"`
	IPAddress       types.String `tfsdk:"ip_address"`
	Libvirtsettings types.Object `tfsdk:"libvirt_settings"`
	ListenSSH       types.Bool   `tfsdk:"listen_ssh"`
	MAC             types.String `tfsdk:"mac"`
	MTU             types.Int64  `tfsdk:"mtu"`
	Name            types.String `tfsdk:"name"`
	NetID           types.Int64  `tfsdk:"net_id"`
	NetMask         types.Int64  `tfsdk:"net_mask"`
	NetType         types.String `tfsdk:"net_type"`
	NodeID          types.Int64  `tfsdk:"node_id"`
	PCISlot         types.Int64  `tfsdk:"pci_slot"`
	QOS             types.Object `tfsdk:"qos"`
	Target          types.String `tfsdk:"target"`
	Type            types.String `tfsdk:"type"`
	VNFs            types.List   `tfsdk:"vnfs"`
}

type LibvirtSettingsModel struct {
	TXMode      types.String `tfsdk:"txmode"`
	IOEventFD   types.String `tfsdk:"ioeventfd"`
	EventIDx    types.String `tfsdk:"event_idx"`
	Queues      types.Int64  `tfsdk:"queues"`
	RXQueueSize types.Int64  `tfsdk:"rx_queue_size"`
	TXQueueSize types.Int64  `tfsdk:"tx_queue_size"`
	GUID        types.String `tfsdk:"guid"`
}

var LibvirtSettings = map[string]attr.Type{
	"txmode":        types.StringType,
	"ioeventfd":     types.StringType,
	"event_idx":     types.StringType,
	"queues":        types.Int64Type,
	"rx_queue_size": types.Int64Type,
	"tx_queue_size": types.Int64Type,
	"guid":          types.StringType,
}

type QOSModel struct {
	ERate   types.Int64  `tfsdk:"e_rate"`
	GUID    types.String `tfsdk:"guid"`
	InBurst types.Int64  `tfsdk:"in_burst"`
	InRate  types.Int64  `tfsdk:"in_rate"`
}

type VINSComputeModel struct {
	ComputeID   types.Int64  `tfsdk:"compute_id"`
	ComputeName types.String `tfsdk:"compute_name"`
}

type RecordVNFsModel struct {
	DHCP types.Object `tfsdk:"dhcp"`
	GW   types.Object `tfsdk:"gw"`
	NAT  types.Object `tfsdk:"nat"`
}

type RecordDHCPModel struct {
	CKey        types.String `tfsdk:"ckey"`
	AccountID   types.Int64  `tfsdk:"account_id"`
	Config      types.Object `tfsdk:"config"`
	CreatedTime types.Int64  `tfsdk:"created_time"`
	Devices     types.Object `tfsdk:"devices"`
	GID         types.Int64  `tfsdk:"gid"`
	GUID        types.Int64  `tfsdk:"guid"`
	DHCPID      types.Int64  `tfsdk:"dhcp_id"`
	LockStatus  types.String `tfsdk:"lock_status"`
	Milestones  types.Int64  `tfsdk:"milestones"`
	OwnerID     types.Int64  `tfsdk:"owner_id"`
	OwnerType   types.String `tfsdk:"owner_type"`
	PureVirtual types.Bool   `tfsdk:"pure_virtual"`
	Routes      types.List   `tfsdk:"routes"`
	Status      types.String `tfsdk:"status"`
	TechStatus  types.String `tfsdk:"tech_status"`
	Type        types.String `tfsdk:"type"`
}

type RoutesModel struct {
	ComputeIds  types.List   `tfsdk:"compute_ids"`
	Destination types.String `tfsdk:"destination"`
	Gateway     types.String `tfsdk:"gateway"`
	GUID        types.String `tfsdk:"guid"`
	RouteID     types.Int64  `tfsdk:"route_id"`
	Netmask     types.String `tfsdk:"netmask"`
}

type DevicesModel struct {
	Primary types.Object `tfsdk:"primary"`
}

type PrimaryDevicesModel struct {
	DevID   types.Int64  `tfsdk:"dev_id"`
	IFace01 types.String `tfsdk:"iface01"`
	IFace02 types.String `tfsdk:"iface02"`
}

type RecordDHCPConfigModel struct {
	DefaultGW    types.String `tfsdk:"default_gw"`
	DNS          types.List   `tfsdk:"dns"`
	IPEnd        types.String `tfsdk:"ip_end"`
	IPStart      types.String `tfsdk:"ip_start"`
	Lease        types.Int64  `tfsdk:"lease"`
	NetMask      types.Int64  `tfsdk:"netmask"`
	Network      types.String `tfsdk:"network"`
	Reservations types.List   `tfsdk:"reservations"`
}

type ReservationModel struct {
	AccountID types.Int64  `tfsdk:"account_id"`
	IP        types.String `tfsdk:"ip"`
	MAC       types.String `tfsdk:"mac"`
	Type      types.String `tfsdk:"type"`
	VMID      types.Int64  `tfsdk:"vm_id"`
}

type RecordNATModel struct {
	CKey        types.String `tfsdk:"ckey"`
	AccountID   types.Int64  `tfsdk:"account_id"`
	Config      types.Object `tfsdk:"config"`
	CreatedTime types.Int64  `tfsdk:"created_time"`
	Devices     types.Object `tfsdk:"devices"`
	GID         types.Int64  `tfsdk:"gid"`
	GUID        types.Int64  `tfsdk:"guid"`
	NatID       types.Int64  `tfsdk:"nat_id"`
	LockStatus  types.String `tfsdk:"lock_status"`
	Milestones  types.Int64  `tfsdk:"milestones"`
	OwnerID     types.Int64  `tfsdk:"owner_id"`
	OwnerType   types.String `tfsdk:"owner_type"`
	PureVirtual types.Bool   `tfsdk:"pure_virtual"`
	Routes      types.List   `tfsdk:"routes"`
	Status      types.String `tfsdk:"status"`
	TechStatus  types.String `tfsdk:"tech_status"`
	Type        types.String `tfsdk:"type"`
}

type NATConfigModel struct {
	NetMask types.Int64  `tfsdk:"net_mask"`
	Network types.String `tfsdk:"network"`
	Rules   types.List   `tfsdk:"rules"`
}

type NATRuleModel struct {
	RuleID          types.Int64  `tfsdk:"rule_id"`
	LocalIP         types.String `tfsdk:"local_ip"`
	LocalPort       types.Int64  `tfsdk:"local_port"`
	Protocol        types.String `tfsdk:"protocol"`
	PublicPortEnd   types.Int64  `tfsdk:"public_port_end"`
	PublicPortStart types.Int64  `tfsdk:"public_port_start"`
	VMID            types.Int64  `tfsdk:"vm_id"`
	VMName          types.String `tfsdk:"vm_name"`
}

type RecordGWModel struct {
	CKey        types.String `tfsdk:"ckey"`
	AccountID   types.Int64  `tfsdk:"account_id"`
	Config      types.Object `tfsdk:"config"`
	CreatedTime types.Int64  `tfsdk:"created_time"`
	Devices     types.Object `tfsdk:"devices"`
	GID         types.Int64  `tfsdk:"gid"`
	GUID        types.Int64  `tfsdk:"guid"`
	GWID        types.Int64  `tfsdk:"gw_id"`
	LockStatus  types.String `tfsdk:"lock_status"`
	Milestones  types.Int64  `tfsdk:"milestones"`
	OwnerID     types.Int64  `tfsdk:"owner_id"`
	OwnerType   types.String `tfsdk:"owner_type"`
	PureVirtual types.Bool   `tfsdk:"pure_virtual"`
	Routes      types.List   `tfsdk:"routes"`
	Status      types.String `tfsdk:"status"`
	TechStatus  types.String `tfsdk:"tech_status"`
	Type        types.String `tfsdk:"type"`
}

type RecordGWConfigModel struct {
	DefaultGW  types.String `tfsdk:"default_gw"`
	ExtNetID   types.Int64  `tfsdk:"ext_net_id"`
	ExtNetIP   types.String `tfsdk:"ext_net_ip"`
	ExtNetMask types.Int64  `tfsdk:"ext_netmask"`
	QOS        types.Object `tfsdk:"qos"`
}

// variables for models

var ItemVNFDev = map[string]attr.Type{
	"ckey":           types.StringType,
	"account_id":     types.Int64Type,
	"capabilities":   types.ListType{ElemType: types.StringType},
	"config":         types.ObjectType{AttrTypes: ItemVNFConfig},
	"config_saved":   types.BoolType,
	"custom_pre_cfg": types.BoolType,
	"desc":           types.StringType,
	"gid":            types.Int64Type,
	"guid":           types.Int64Type,
	"vnf_id":         types.Int64Type,
	"interfaces":     types.ListType{ElemType: types.ObjectType{AttrTypes: ItemInterface}},
	"lock_status":    types.StringType,
	"milestones":     types.Int64Type,
	"vnf_name":       types.StringType,
	"status":         types.StringType,
	"tech_status":    types.StringType,
	"type":           types.StringType,
	"vnc_password":   types.StringType,
	"vins":           types.ListType{ElemType: types.Int64Type},
}

var ItemInterface = map[string]attr.Type{
	"bus_number":       types.Int64Type,
	"conn_id":          types.Int64Type,
	"conn_type":        types.StringType,
	"def_gw":           types.StringType,
	"enabled":          types.BoolType,
	"flipgroup_id":     types.Int64Type,
	"guid":             types.StringType,
	"ip_address":       types.StringType,
	"libvirt_settings": types.ObjectType{AttrTypes: LibvirtSettings},
	"listen_ssh":       types.BoolType,
	"mac":              types.StringType,
	"mtu":              types.Int64Type,
	"name":             types.StringType,
	"net_id":           types.Int64Type,
	"net_mask":         types.Int64Type,
	"net_type":         types.StringType,
	"node_id":          types.Int64Type,
	"pci_slot":         types.Int64Type,
	"qos":              types.ObjectType{AttrTypes: ItemQOS},
	"target":           types.StringType,
	"type":             types.StringType,
	"vnfs":             types.ListType{ElemType: types.Int64Type},
}

var ItemQOS = map[string]attr.Type{
	"e_rate":   types.Int64Type,
	"guid":     types.StringType,
	"in_burst": types.Int64Type,
	"in_rate":  types.Int64Type,
}

var ItemVNFConfig = map[string]attr.Type{
	"mgmt":      types.ObjectType{AttrTypes: ItemMgmt},
	"resources": types.ObjectType{AttrTypes: ItemResources},
}

var ItemMgmt = map[string]attr.Type{
	"ip_addr":  types.StringType,
	"password": types.StringType,
	"ssh_key":  types.StringType,
	"user":     types.StringType,
}

var ItemResources = map[string]attr.Type{
	"cpu":      types.Int64Type,
	"ram":      types.Int64Type,
	"stack_id": types.Int64Type,
	"uuid":     types.StringType,
}

var ItemVNFs = map[string]attr.Type{
	"dhcp": types.ObjectType{AttrTypes: ItemDHCP},
	"gw":   types.ObjectType{AttrTypes: ItemGW},
	"nat":  types.ObjectType{AttrTypes: ItemNAT},
}

var ItemDHCP = map[string]attr.Type{
	"ckey":         types.StringType,
	"account_id":   types.Int64Type,
	"config":       types.ObjectType{AttrTypes: ItemDHCPConfig},
	"created_time": types.Int64Type,
	"devices":      types.ObjectType{AttrTypes: ItemDevices},
	"gid":          types.Int64Type,
	"guid":         types.Int64Type,
	"dhcp_id":      types.Int64Type,
	"lock_status":  types.StringType,
	"milestones":   types.Int64Type,
	"owner_id":     types.Int64Type,
	"owner_type":   types.StringType,
	"pure_virtual": types.BoolType,
	"routes":       types.ListType{ElemType: types.ObjectType{AttrTypes: ItemRoute}},
	"status":       types.StringType,
	"tech_status":  types.StringType,
	"type":         types.StringType,
}

var ItemRoute = map[string]attr.Type{
	"compute_ids": types.ListType{ElemType: types.Int64Type},
	"destination": types.StringType,
	"gateway":     types.StringType,
	"guid":        types.StringType,
	"route_id":    types.Int64Type,
	"netmask":     types.StringType,
}

var ItemDevices = map[string]attr.Type{
	"primary": types.ObjectType{AttrTypes: ItemPrimaryDevices},
}
var ItemPrimaryDevices = map[string]attr.Type{
	"dev_id":  types.Int64Type,
	"iface01": types.StringType,
	"iface02": types.StringType,
}

var ItemDHCPConfig = map[string]attr.Type{
	"default_gw":   types.StringType,
	"dns":          types.ListType{ElemType: types.StringType},
	"ip_end":       types.StringType,
	"ip_start":     types.StringType,
	"lease":        types.Int64Type,
	"netmask":      types.Int64Type,
	"network":      types.StringType,
	"reservations": types.ListType{ElemType: types.ObjectType{AttrTypes: ItemReservations}},
}

var ItemReservations = map[string]attr.Type{
	"account_id": types.Int64Type,
	"ip":         types.StringType,
	"mac":        types.StringType,
	"type":       types.StringType,
	"vm_id":      types.Int64Type,
}

var ItemGW = map[string]attr.Type{
	"ckey":         types.StringType,
	"account_id":   types.Int64Type,
	"config":       types.ObjectType{AttrTypes: ItemGWConfig},
	"created_time": types.Int64Type,
	"devices":      types.ObjectType{AttrTypes: ItemDevices},
	"gid":          types.Int64Type,
	"guid":         types.Int64Type,
	"gw_id":        types.Int64Type,
	"lock_status":  types.StringType,
	"milestones":   types.Int64Type,
	"owner_id":     types.Int64Type,
	"owner_type":   types.StringType,
	"pure_virtual": types.BoolType,
	"routes":       types.ListType{ElemType: types.ObjectType{AttrTypes: ItemRoute}},
	"status":       types.StringType,
	"tech_status":  types.StringType,
	"type":         types.StringType,
}

var ItemGWConfig = map[string]attr.Type{
	"default_gw":  types.StringType,
	"ext_net_id":  types.Int64Type,
	"ext_net_ip":  types.StringType,
	"ext_netmask": types.Int64Type,
	"qos":         types.ObjectType{AttrTypes: ItemQOS},
}

var ItemNAT = map[string]attr.Type{
	"ckey":         types.StringType,
	"account_id":   types.Int64Type,
	"config":       types.ObjectType{AttrTypes: ItemNATConfig},
	"created_time": types.Int64Type,
	"devices":      types.ObjectType{AttrTypes: ItemDevices},
	"gid":          types.Int64Type,
	"guid":         types.Int64Type,
	"nat_id":       types.Int64Type,
	"lock_status":  types.StringType,
	"milestones":   types.Int64Type,
	"owner_id":     types.Int64Type,
	"owner_type":   types.StringType,
	"pure_virtual": types.BoolType,
	"routes":       types.ListType{ElemType: types.ObjectType{AttrTypes: ItemRoute}},
	"status":       types.StringType,
	"tech_status":  types.StringType,
	"type":         types.StringType,
}

var ItemNATConfig = map[string]attr.Type{
	"net_mask": types.Int64Type,
	"network":  types.StringType,
	"rules":    types.ListType{ElemType: types.ObjectType{AttrTypes: ItemNATRule}},
}

var ItemNATRule = map[string]attr.Type{
	"rule_id":           types.Int64Type,
	"local_ip":          types.StringType,
	"local_port":        types.Int64Type,
	"protocol":          types.StringType,
	"public_port_end":   types.Int64Type,
	"public_port_start": types.Int64Type,
	"vm_id":             types.Int64Type,
	"vm_name":           types.StringType,
}

var ItemCompute = map[string]attr.Type{
	"compute_id":   types.Int64Type,
	"compute_name": types.StringType,
}
