package models

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

type ResourceRGModel struct {
	// request fields - required
	AccountID types.Int64  `tfsdk:"account_id"`
	GID       types.Int64  `tfsdk:"gid"`
	Name      types.String `tfsdk:"name"`

	// request fields - optional
	DefNetType  types.String   `tfsdk:"def_net_type"`
	IPCIDR      types.String   `tfsdk:"ipcidr"`
	ExtNetID    types.Int64    `tfsdk:"ext_net_id"`
	ExtIP       types.String   `tfsdk:"ext_ip"`
	Owner       types.String   `tfsdk:"owner"`
	Quota       types.Object   `tfsdk:"quota"`
	Access      types.Set      `tfsdk:"access"`
	DefNet      types.Object   `tfsdk:"def_net"`
	Description types.String   `tfsdk:"description"`
	Force       types.Bool     `tfsdk:"force"`
	Permanently types.Bool     `tfsdk:"permanently"`
	Restore     types.Bool     `tfsdk:"restore"`
	Enable      types.Bool     `tfsdk:"enable"`
	Timeouts    timeouts.Value `tfsdk:"timeouts"`

	// response fields
	RGID                   types.Int64   `tfsdk:"rg_id"`
	LastUpdated            types.String  `tfsdk:"last_updated"`
	AccountName            types.String  `tfsdk:"account_name"`
	ACL                    types.List    `tfsdk:"acl"`
	ComputeFeatures        types.List    `tfsdk:"compute_features"`
	CPUAllocationParameter types.String  `tfsdk:"cpu_allocation_parameter"`
	CPUAllocationRatio     types.Float64 `tfsdk:"cpu_allocation_ratio"`
	DefNetID               types.Int64   `tfsdk:"def_net_id"`
	CreatedBy              types.String  `tfsdk:"created_by"`
	CreatedTime            types.Int64   `tfsdk:"created_time"`
	DeletedBy              types.String  `tfsdk:"deleted_by"`
	DeletedTime            types.Int64   `tfsdk:"deleted_time"`
	Dirty                  types.Bool    `tfsdk:"dirty"`
	GUID                   types.Int64   `tfsdk:"guid"`
	Id                     types.String  `tfsdk:"id"`
	LockStatus             types.String  `tfsdk:"lock_status"`
	Milestones             types.Int64   `tfsdk:"milestones"`
	ResTypes               types.List    `tfsdk:"res_types"`
	Secret                 types.String  `tfsdk:"secret"`
	Status                 types.String  `tfsdk:"status"`
	UniqPools              types.List    `tfsdk:"uniq_pools"`
	UpdatedBy              types.String  `tfsdk:"updated_by"`
	UpdatedTime            types.Int64   `tfsdk:"updated_time"`
	VINS                   types.List    `tfsdk:"vins"`
	VMS                    types.List    `tfsdk:"vms"`
}

type ItemACLModel struct {
	Explicit    types.Bool   `tfsdk:"explicit"`
	GUID        types.String `tfsdk:"guid"`
	Right       types.String `tfsdk:"right"`
	Status      types.String `tfsdk:"status"`
	Type        types.String `tfsdk:"type"`
	UserGroupID types.String `tfsdk:"user_group_id"`
}

type QuotaModel struct {
	CPU        types.Int64 `tfsdk:"cpu"`
	Ram        types.Int64 `tfsdk:"ram"`
	Disk       types.Int64 `tfsdk:"disk"`
	ExtTraffic types.Int64 `tfsdk:"ext_traffic"`
	ExtIps     types.Int64 `tfsdk:"ext_ips"`
	GpuUnits   types.Int64 `tfsdk:"gpu_units"`
	CuD        types.Int64 `tfsdk:"cu_d"`
}

type AccessModel struct {
	User  types.String `tfsdk:"user"`
	Right types.String `tfsdk:"right"`
}

type DefNetModel struct {
	NetType types.String `tfsdk:"net_type"`
	NetId   types.Int64  `tfsdk:"net_id"`
}

var ItemAccess = map[string]attr.Type{
	"user":  types.StringType,
	"right": types.StringType,
}

var ItemDefNet = map[string]attr.Type{
	"net_type": types.StringType,
	"net_id":   types.Int64Type,
}

var ItemACL = map[string]attr.Type{
	"explicit":      types.BoolType,
	"guid":          types.StringType,
	"right":         types.StringType,
	"status":        types.StringType,
	"type":          types.StringType,
	"user_group_id": types.StringType,
}

var ItemQuota = map[string]attr.Type{
	"cpu":         types.Int64Type,
	"ram":         types.Int64Type,
	"disk":        types.Int64Type,
	"ext_traffic": types.Int64Type,
	"ext_ips":     types.Int64Type,
	"gpu_units":   types.Int64Type,
	"cu_d":        types.Int64Type,
}

// Contains returns true if accessList contains a as an element. Otherwise it returns false.
func (a *AccessModel) Contains(accessList []AccessModel) bool {
	for _, accessElem := range accessList {
		if a.User.Equal(accessElem.User) && a.Right.Equal(accessElem.Right) {
			return true
		}
	}
	return false
}
