package schemas

import (
	"github.com/hashicorp/terraform-plugin-framework-validators/int64validator"
	"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
	"github.com/hashicorp/terraform-plugin-framework/resource/schema"
	"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
	"github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier"
	"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
	"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
	"github.com/hashicorp/terraform-plugin-framework/schema/validator"
	"github.com/hashicorp/terraform-plugin-framework/types"
	"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/constants"
	"repository.basistech.ru/BASIS/terraform-provider-dynamix/internal/validate"
)

func MakeSchemaResourceK8SCP() map[string]schema.Attribute {
	return map[string]schema.Attribute{
		// required attributes
		"name": schema.StringAttribute{
			Required:    true,
			Description: "Name of the cluster.",
		},
		"rg_id": schema.Int64Attribute{
			Required:    true,
			Description: "Resource group ID that this instance belongs to.",
		},
		"k8sci_id": schema.Int64Attribute{
			Required:    true,
			Description: "ID of the k8s catalog item to base this instance on.",
		},
		"network_plugin": schema.StringAttribute{
			Required: true,
			Validators: []validator.String{
				stringvalidator.OneOf("flannel", "weavenet", "calico"),
			},
			Description: "Network plugin to be used",
		},
		// optional attributes for create
		"sep_id": schema.Int64Attribute{
			Optional:    true,
			Description: "Storage Endpoint ID",
		},
		"sep_pool": schema.StringAttribute{
			Optional:    true,
			Description: "Storage Endpoint Pool",
		},
		"num": schema.Int64Attribute{
			Optional: true,
			Computed: true,
			Validators: []validator.Int64{
				int64validator.OneOf(1, 3, 5),
			},
			PlanModifiers: []planmodifier.Int64{
				int64planmodifier.UseStateForUnknown(),
			},
			Description: "Number of VMs to create. Can be either 1,3 or 5",
		},
		"cpu": schema.Int64Attribute{
			Optional:    true,
			Computed:    true,
			Description: "Node CPU count.",
		},
		"ram": schema.Int64Attribute{
			Optional:    true,
			Computed:    true,
			Description: "Node RAM in MB.",
			Validators: []validator.Int64{
				validate.DivisibleBy(constants.DivisibleByRAM),
			},
		},
		"disk": schema.Int64Attribute{
			Optional:    true,
			Computed:    true,
			Description: "Node boot disk size in GB.",
		},
		"extnet_id": schema.Int64Attribute{
			Optional:    true,
			Computed:    true,
			Description: "ID of the external network to connect workers to. If omitted network will be chosen by the platfom.",
		},
		"vins_id": schema.Int64Attribute{
			Optional:    true,
			Computed:    true,
			Description: "ID of default vins for this instace.",
		},
		"with_lb": schema.BoolAttribute{
			Optional:    true,
			Computed:    true,
			Default:     booldefault.StaticBool(true),
			Description: "Create k8s with load balancer if true.",
		},
		"ha_mode": schema.BoolAttribute{
			Optional:    true,
			Computed:    true,
			Default:     booldefault.StaticBool(false),
			Description: "Use Highly Available schema for LB deploy",
		},
		"additional_sans": schema.ListAttribute{
			Optional:    true,
			ElementType: types.StringType,
			Description: "is used to define settings and actions that should be performed before any other component in the cluster starts. It allows you to configure things like node registration, network setup, and other initialization tasks. insert a valid JSON string with all levels of nesting.",
		},
		"init_config": schema.StringAttribute{
			Optional:    true,
			Description: "is used to define settings and actions that should be performed before any other component in the cluster starts. It allows you to configure things like node registration, network setup, and other initialization tasks. insert a valid JSON string with all levels of nesting.",
		},
		"cluster_config": schema.StringAttribute{
			Optional:    true,
			Description: "is used to configure the behavior and settings of the Kube-proxy, which is responsible for network proxying and load balancing within the cluster. It includes parameters such as proxy mode, cluster IP ranges, and other Kube-proxy specific configurations. insert a valid JSON string with all levels of nesting.",
		},
		"kubelet_config": schema.StringAttribute{
			Optional:    true,
			Description: "is used to configure the behavior and settings of the Kube-proxy, which is responsible for network proxying and load balancing within the cluster. It includes parameters such as proxy mode, cluster IP ranges, and other Kube-proxy specific configurations. insert a valid JSON string with all levels of nesting.",
		},
		"kube_proxy_config": schema.StringAttribute{
			Optional:    true,
			Description: "is used to configure the behavior and settings of the Kube-proxy, which is responsible for network proxying and load balancing within the cluster. It includes parameters such as proxy mode, cluster IP ranges, and other Kube-proxy specific configurations. insert a valid JSON string with all levels of nesting.",
		},
		"join_config": schema.StringAttribute{
			Optional:    true,
			Description: "is used to configure the behavior and settings for joining a node to a cluster. It includes parameters such as the cluster's control plane endpoint, token, and certificate key. insert a valid JSON string with all levels of nesting.",
		},
		"desc": schema.StringAttribute{
			Optional:    true,
			Computed:    true,
			Description: "Text description of this instance.",
		},
		"extnet_only": schema.BoolAttribute{
			Optional:    true,
			Computed:    true,
			Default:     booldefault.StaticBool(false),
			Description: "Use only selected ExtNet for infrastructure connections",
		},
		"oidc_cert": schema.StringAttribute{
			Optional:    true,
			Description: "Insert ssl certificate in x509 pem format",
		},
		"chipset": schema.StringAttribute{
			Optional:    true,
			Description: "Type of the emulated system",
			Validators: []validator.String{
				stringvalidator.OneOfCaseInsensitive("Q35", "i440fx"),
			},
		},
		"lb_sysctl_params": schema.ListNestedAttribute{
			Optional:    true,
			Description: "Custom sysctl values for Load Balancer instance. Applied on boot.",
			NestedObject: schema.NestedAttributeObject{
				Attributes: map[string]schema.Attribute{
					"key": schema.StringAttribute{
						Required: true,
					},
					"value": schema.StringAttribute{
						Required: true,
					},
				},
			},
		},
		// optional attributes for update
		"start": schema.BoolAttribute{
			Optional:    true,
			Computed:    true,
			Default:     booldefault.StaticBool(false),
			Description: "Start k8s cluster.",
		},
		"enabled": schema.BoolAttribute{
			Optional:    true,
			Computed:    true,
			Default:     booldefault.StaticBool(true),
			Description: "Enable k8s cluster",
		},
		"permanently": schema.BoolAttribute{
			Optional:    true,
			Computed:    true,
			Default:     booldefault.StaticBool(true),
			Description: "whether to completely delete the k8s cluster",
		},
		"restore": schema.BoolAttribute{
			Optional:    true,
			Computed:    true,
			Default:     booldefault.StaticBool(true),
			Description: "if true, restore the k8s cluster from Recycle Bin",
		},
		// computed attributes
		"id": schema.StringAttribute{
			Computed: true,
			PlanModifiers: []planmodifier.String{
				stringplanmodifier.UseStateForUnknown(),
			},
		},
		"last_updated": schema.StringAttribute{
			Computed:    true,
			Description: "Timestamp of the last Terraform update of the order.",
		},
		"master_group_id": schema.Int64Attribute{
			Computed:    true,
			Description: "Master group ID.",
		},
		"master_group_name": schema.StringAttribute{
			Computed:    true,
			Description: "Master group name.",
		},
		"acl": schema.SingleNestedAttribute{
			Computed: true,
			Attributes: map[string]schema.Attribute{
				"account_acl": schema.ListNestedAttribute{
					Computed: true,
					NestedObject: schema.NestedAttributeObject{
						Attributes: map[string]schema.Attribute{
							"explicit": schema.BoolAttribute{
								Computed: true,
							},
							"guid": schema.StringAttribute{
								Computed: true,
							},
							"right": schema.StringAttribute{
								Computed: true,
							},
							"status": schema.StringAttribute{
								Computed: true,
							},
							"type": schema.StringAttribute{
								Computed: true,
							},
							"user_group_id": schema.StringAttribute{
								Computed: true,
							},
						},
					},
				},
				"k8s_acl": schema.ListNestedAttribute{
					Computed: true,
					NestedObject: schema.NestedAttributeObject{
						Attributes: map[string]schema.Attribute{
							"explicit": schema.BoolAttribute{
								Computed: true,
							},
							"guid": schema.StringAttribute{
								Computed: true,
							},
							"right": schema.StringAttribute{
								Computed: true,
							},
							"status": schema.StringAttribute{
								Computed: true,
							},
							"type": schema.StringAttribute{
								Computed: true,
							},
							"user_group_id": schema.StringAttribute{
								Computed: true,
							},
						},
					},
				},
				"rg_acl": schema.ListNestedAttribute{
					Computed: true,
					NestedObject: schema.NestedAttributeObject{
						Attributes: map[string]schema.Attribute{
							"explicit": schema.BoolAttribute{
								Computed: true,
							},
							"guid": schema.StringAttribute{
								Computed: true,
							},
							"right": schema.StringAttribute{
								Computed: true,
							},
							"status": schema.StringAttribute{
								Computed: true,
							},
							"type": schema.StringAttribute{
								Computed: true,
							},
							"user_group_id": schema.StringAttribute{
								Computed: true,
							},
						},
					},
				},
			},
		},
		"detailed_info": schema.ListNestedAttribute{
			Computed: true,
			NestedObject: schema.NestedAttributeObject{
				Attributes: map[string]schema.Attribute{
					"compute_id": schema.Int64Attribute{
						Computed: true,
					},
					"name": schema.StringAttribute{
						Computed: true,
					},
					"status": schema.StringAttribute{
						Computed: true,
					},
					"tech_status": schema.StringAttribute{
						Computed: true,
					},
					"interfaces": schema.ListNestedAttribute{
						Computed: true,
						NestedObject: schema.NestedAttributeObject{
							Attributes: map[string]schema.Attribute{
								"def_gw": schema.StringAttribute{
									Computed: true,
								},
								"ip_address": schema.StringAttribute{
									Computed: true,
								},
							},
						},
					},
					"natable_vins_ip": schema.StringAttribute{
						Computed: true,
					},
					"natable_vins_network": schema.StringAttribute{
						Computed: true,
					},
				},
			},
		},
		"account_id": schema.Int64Attribute{
			Computed: true,
		},
		"account_name": schema.StringAttribute{
			Computed: true,
		},
		"address_vip": schema.SingleNestedAttribute{
			Computed: true,
			Attributes: map[string]schema.Attribute{
				"backend_ip": schema.StringAttribute{
					Computed: true,
				},
				"frontend_ip": schema.StringAttribute{
					Computed: true,
				},
			},
		},
		"bservice_id": schema.Int64Attribute{
			Computed: true,
		},
		"created_by": schema.StringAttribute{
			Computed: true,
		},
		"created_time": schema.Int64Attribute{
			Computed: true,
		},
		"deleted_by": schema.StringAttribute{
			Computed: true,
		},
		"deleted_time": schema.Int64Attribute{
			Computed: true,
		},
		"k8s_ci_name": schema.StringAttribute{
			Computed: true,
		},
		"lb_id": schema.Int64Attribute{
			Computed: true,
		},
		"k8s_id": schema.Int64Attribute{
			Computed: true,
			PlanModifiers: []planmodifier.Int64{
				int64planmodifier.UseStateForUnknown(),
			},
		},
		"lb_ip": schema.StringAttribute{
			Computed: true,
		},
		"rg_name": schema.StringAttribute{
			Computed: true,
		},
		"status": schema.StringAttribute{
			Computed: true,
		},
		"tech_status": schema.StringAttribute{
			Computed: true,
		},
		"updated_by": schema.StringAttribute{
			Computed: true,
		},
		"updated_time": schema.Int64Attribute{
			Computed: true,
		},
		"kubeconfig": schema.StringAttribute{
			Computed: true,
		},
	}
}
