package models

import (
	"fmt"
	"github.com/tidbcloud/idl/pbgen/proto/openapi/cm"
)

type QueryPageParam struct {
	Page     int `url:"page"`
	PageSize int `url:"page_size"`
}

type CreateClusterReq struct {
	Name          string         `json:"name,omitempty"`
	ClusterType   string         `json:"cluster_type,omitempty"`
	CloudProvider string         `json:"cloud_provider,omitempty"`
	Region        string         `json:"region,omitempty"`
	Config        *ClusterConfig `json:"config,omitempty"`
}

func (config *ClusterConfig) String() string {
	return fmt.Sprintf("{port:%d,components:%+v,ip_access_list:%+v}", config.Port, config.Components, config.IpAccessList)
}

type ClusterConfig struct {
	RootPassword string              `json:"root_password,omitempty"`
	Port         int32               `json:"port,omitempty"`
	Components   *ClusterComponents  `json:"components,omitempty"`
	IpAccessList []*IpAccessListItem `json:"ip_access_list,omitempty"`
}

func (components *ClusterComponents) String() string {
	return fmt.Sprintf("{tidb:%+v,tikv:%+v,tiflash:%+v}", components.Tidb, components.Tikv, components.Tiflash)
}

func (ip *IpAccessListItem) String() string {
	return fmt.Sprintf("{cidr:%s,desc:%s}", ip.Cidr, ip.Description)
}

type IpAccessListItem struct {
	Cidr        string `json:"cidr,omitempty"`
	Description string `json:"description,omitempty"`
}

type ClusterComponents struct {
	Tidb    *TiDBComponent    `json:"tidb,omitempty"`
	Tikv    *TiKVComponent    `json:"tikv,omitempty"`
	Tiflash *TiFlashComponent `json:"tiflash,omitempty"`
}

func (tidb *TiDBComponent) String() string {
	if tidb == nil {
		return ""
	}
	return fmt.Sprintf("{node size:%s,storage_size_gib:%d,node_quantity:%d}", tidb.NodeSize, tidb.StorageSizeGib, tidb.NodeQuantity)
}

type TiDBComponent struct {
	NodeSize       string `json:"node_size,omitempty"`
	StorageSizeGib int32  `json:"storage_size_gib,omitempty"`
	NodeQuantity   int32  `json:"node_quantity,omitempty"`
}

func (tikv *TiKVComponent) String() string {
	if tikv == nil {
		return ""
	}
	return fmt.Sprintf("{node size:%s,storage_size_gib:%d,node_quantity:%d}", tikv.NodeSize, tikv.StorageSizeGib, tikv.NodeQuantity)
}

func (tiflash *TiFlashComponent) String() string {
	if tiflash == nil {
		return ""
	}
	return fmt.Sprintf("{node size:%s,storage_size_gib:%d,node_quantity:%d}", tiflash.NodeSize, tiflash.StorageSizeGib, tiflash.NodeQuantity)
}

type TiKVComponent struct {
	NodeSize       string `json:"node_size,omitempty"`
	StorageSizeGib int32  `json:"storage_size_gib,omitempty"`
	NodeQuantity   int32  `json:"node_quantity,omitempty"`
}

type TiFlashComponent struct {
	NodeSize       string `json:"node_size,omitempty"`
	StorageSizeGib int32  `json:"storage_size_gib,omitempty"`
	NodeQuantity   int32  `json:"node_quantity,omitempty"`
}

type ClusterNodeSpec struct {
	NodeType       string `json:"node_type,omitempty"`
	NodeSize       string `json:"node_size,omitempty"`
	VcpuNum        int32  `json:"vcpu_num,omitempty"`
	RamBytes       string `json:"ram_bytes,omitempty"`
	StorageSizeGib int32  `json:"storage_size_gib,omitempty"`
	NodeQuantity   int32  `json:"node_quantity,omitempty"`
}

type ListProviderRegionsResp struct {
	Items []*ListProviderRegionsItem `json:"items,omitempty"`
}

func (item *ListProviderRegionsItem) String() string {
	return fmt.Sprintf("{cluster_type:%s,cloud_provider:%s,region:%s,tidb:%+v,tikv:%+v,tiflash:%+v}", item.ClusterType, item.CloudProvider, item.Region, item.Tidb, item.Tikv, item.Tiflash)
}

type ListProviderRegionsItem struct {
	ClusterType   string            `json:"cluster_type,omitempty"`
	CloudProvider string            `json:"cloud_provider,omitempty"`
	Region        string            `json:"region,omitempty"`
	Tidb          []*TiDBProfile    `json:"tidb,omitempty"`
	Tikv          []*TiKVProfile    `json:"tikv,omitempty"`
	Tiflash       []*TiFlashProfile `json:"tiflash,omitempty"`
}

func (tidb *TiDBProfile) String() string {
	if tidb == nil {
		return ""
	}
	return fmt.Sprintf("{node_size:%s,node_quantity_range:%+v}", tidb.NodeSize, tidb.NodeQuantityRange)
}

type TiDBProfile struct {
	NodeSize          string             `json:"node_size,omitempty"`
	NodeQuantityRange *NodeQuantityRange `json:"node_quantity_range,omitempty"`
}

func (tikv *TiKVProfile) String() string {
	if tikv == nil {
		return ""
	}
	return fmt.Sprintf("{node_size:%s,node_quantity_range:%+v,storage_size_gib_range:%+v}", tikv.NodeSize, tikv.NodeQuantityRange, tikv.StorageSizeGibRange)
}

type TiKVProfile struct {
	NodeSize            string                `json:"node_size,omitempty"`
	NodeQuantityRange   *NodeQuantityRange    `json:"node_quantity_range,omitempty"`
	StorageSizeGibRange *NodeStorageSizeRange `json:"storage_size_gib_range,omitempty"`
}

func (tiflash *TiFlashProfile) String() string {
	if tiflash == nil {
		return ""
	}
	return fmt.Sprintf("{node_size:%s,node_quantity_range:%+v,storage_size_gib_range:%+v}", tiflash.NodeSize, tiflash.NodeQuantityRange, tiflash.StorageSizeGibRange)
}

type TiFlashProfile struct {
	NodeSize            string                `json:"node_size,omitempty"`
	NodeQuantityRange   *NodeQuantityRange    `json:"node_quantity_range,omitempty"`
	StorageSizeGibRange *NodeStorageSizeRange `json:"storage_size_gib_range,omitempty"`
}

func (n *NodeQuantityRange) String() string {
	return fmt.Sprintf("{min:%d,step:%d}", n.Min, n.Step)
}

type NodeQuantityRange struct {
	Min  int32 `json:"min,omitempty"`
	Step int32 `json:"step,omitempty"`
}

func (n *NodeStorageSizeRange) String() string {
	return fmt.Sprintf("{min:%d,max:%d}", n.Min, n.Max)
}

type NodeStorageSizeRange struct {
	Min int32 `json:"min,omitempty"`
	Max int32 `json:"max,omitempty"`
}

type UpdateClusterReq struct {
	Config *UpdateClusterConfig `json:"config,omitempty"`
}

func (config *UpdateClusterConfig) String() string {
	if config == nil {
		return ""
	}
	return fmt.Sprintf("{components:%+v,Paused:%+v}", config.Components, config.Paused)
}

type UpdateClusterConfig struct {
	Components *UpdateClusterComponents `json:"components,omitempty"`
	Paused     *bool                    ` json:"paused,omitempty"`
}

func (components *UpdateClusterComponents) String() string {
	if components == nil {
		return ""
	}
	return fmt.Sprintf("{tidb%+v,tikv:%+v,tiflash:%+v}", components.Tidb, components.Tikv, components.Tiflash)
}

type UpdateClusterComponents struct {
	Tidb    *UpdateTiDBComponent    `json:"tidb,omitempty"`
	Tikv    *UpdateTiKVComponent    `json:"tikv,omitempty"`
	Tiflash *UpdateTiFlashComponent `json:"tiflash,omitempty"`
}

func (n *UpdateTiDBComponent) String() string {
	if n == nil {
		return ""
	}
	return fmt.Sprintf("{node_quantity:%d, node_size:%s, accesspoint_id:%s}", n.NodeQuantity, n.NodeSize, n.AccesspointId)
}

type UpdateTiDBComponent struct {
	NodeQuantity  int32  `json:"node_quantity,omitempty"`
	NodeSize      string `json:"node_size,omitempty"`
	AccesspointId string `json:"accesspoint_id,omitempty"`
}

func (n *UpdateTiKVComponent) String() string {
	if n == nil {
		return ""
	}
	return fmt.Sprintf("{node_quantity:%d,node_size:%s,storage_size_gib:%d}", n.NodeQuantity, n.NodeSize, n.StorageSizeGib)
}

type UpdateTiKVComponent struct {
	NodeQuantity   int32  `json:"node_quantity,omitempty"`
	NodeSize       string `json:"node_size,omitempty"`
	StorageSizeGib int32  `json:"storage_size_gib,omitempty"`
}

func (n *UpdateTiFlashComponent) String() string {
	if n == nil {
		return ""
	}
	return fmt.Sprintf("{node_quantity:%d,node_size:%s,storage_size_gib:%d}", n.NodeQuantity, n.NodeSize, n.StorageSizeGib)
}

type UpdateTiFlashComponent struct {
	NodeQuantity   int32  `json:"node_quantity"`
	NodeSize       string `json:"node_size,omitempty"`
	StorageSizeGib int32  `json:"storage_size_gib,omitempty"`
}

type UpdateClusterNodeSpec struct {
	NodeType       string `json:"node_type,omitempty"`
	NodeSize       string `json:"node_size,omitempty"`
	StorageSizeGib int32  `json:"storage_size_gib,omitempty"`
	NodeQuantity   int32  `json:"node_quantity,omitempty"`
}

type ProviderAvailableRegion struct {
	CloudProvider string `json:"cloud_provider,omitempty"`
	Name          string `json:"name,omitempty"`
}

type ClusterNode struct {
	NodeName         string `json:"node_name,omitempty"`
	NodeType         string `json:"node_type,omitempty"`
	AvailabilityZone string `json:"availability_zone,omitempty"`
	NodeSize         string `json:"node_size,omitempty"`
	VcpuNum          int32  `json:"vcpu_num,omitempty"`
	RamBytes         string `json:"ram_bytes,omitempty"`
	StorageSizeGib   int32  `json:"storage_size_gib,omitempty"`
	Status           string `json:"status,omitempty"`
}

type ListClustersOfProjectResp struct {
	Items []*ClusterItem `json:"items,omitempty"`
	Total uint32         `json:"total,omitempty"`
}

func (item *ClusterItem) String() string {
	if item == nil {
		return ""
	}
	return fmt.Sprintf("{id:%s,project_id:%s,name:%s,cluster_type:%s,cloud_provider:%s,region:%s,create_timestamp:%s,config:%+v,status:%+v}", item.Id, item.ProjectId, item.Name, item.ClusterType, item.CloudProvider, item.Region, item.CreateTimestamp, item.Config, item.Status)
}

type ClusterItem struct {
	Id              string             `json:"id,omitempty"`
	ProjectId       string             `json:"project_id,omitempty"`
	Name            string             `json:"name,omitempty"`
	ClusterType     string             `json:"cluster_type,omitempty"`
	CloudProvider   string             `json:"cloud_provider,omitempty"`
	Region          string             `json:"region,omitempty"`
	CreateTimestamp string             `json:"create_timestamp,omitempty"`
	Config          *GetClusterConfig  `json:"config,omitempty"`
	Status          *ClusterItemStatus `json:"status,omitempty"`
}

func (config *GetClusterConfig) String() string {
	if config == nil {
		return ""
	}
	return fmt.Sprintf("{port:%d,components:%+v}", config.Port, config.Components)
}

type GetClusterConfig struct {
	Port       int32              `json:"port,omitempty"`
	Components *ClusterComponents `json:"components,omitempty"`
}

func (status *ClusterItemStatus) String() string {
	if status == nil {
		return ""
	}
	return fmt.Sprintf("{tidb_version:%s,cluster_status:%s,node_map:%+v,connection_strings:%+v}", status.TidbVersion, status.ClusterStatus, status.NodeMap, status.ConnectionStrings)
}

type ClusterItemStatus struct {
	TidbVersion       string                       `json:"tidb_version,omitempty"`
	ClusterStatus     string                       `json:"cluster_status,omitempty"`
	NodeMap           *ClusterNodeMap              `json:"node_map,omitempty"`
	ConnectionStrings *cm.ClusterConnectionStrings `json:"connection_strings,omitempty"`
}

func (n *ClusterNodeMap) String() string {
	if n == nil {
		return ""
	}
	return fmt.Sprintf("{tidb:%+v,tikv:%+v,tiflash:%+v}", n.Tidb, n.Tikv, n.Tiflash)
}

type ClusterNodeMap struct {
	Tidb    []*TiDBNodeMap    `json:"tidb,omitempty"`
	Tikv    []*TiKVNodeMap    `json:"tikv,omitempty"`
	Tiflash []*TiFlashNodeMap `json:"tiflash,omitempty"`
}

func (tidb *TiDBNodeMap) String() string {
	if tidb == nil {
		return ""
	}
	return fmt.Sprintf("{node_name:%s,availability_zone:%s,node_size:%s,vcpu_num:%d,ram_bytes:%s,storage_size_gib:%d,status:%s}", tidb.NodeName, tidb.AvailabilityZone, tidb.NodeSize, tidb.VcpuNum, tidb.RamBytes, tidb.StorageSizeGib, tidb.Status)
}

type TiDBNodeMap struct {
	NodeName         string `json:"node_name,omitempty"`
	AvailabilityZone string `json:"availability_zone,omitempty"`
	NodeSize         string `json:"node_size,omitempty"`
	VcpuNum          int32  `json:"vcpu_num,omitempty"`
	RamBytes         string `json:"ram_bytes,omitempty"`
	StorageSizeGib   int32  `json:"storage_size_gib,omitempty"`
	Status           string `json:"status,omitempty"`
}

func (tikv *TiKVNodeMap) String() string {
	if tikv == nil {
		return ""
	}
	return fmt.Sprintf("{node_name:%s,availability_zone:%s,node_size:%s,vcpu_num:%d,ram_bytes:%s,storage_size_gib:%d,status:%s}", tikv.NodeName, tikv.AvailabilityZone, tikv.NodeSize, tikv.VcpuNum, tikv.RamBytes, tikv.StorageSizeGib, tikv.Status)
}

type TiKVNodeMap struct {
	NodeName         string `json:"node_name,omitempty"`
	AvailabilityZone string `json:"availability_zone,omitempty"`
	NodeSize         string `json:"node_size,omitempty"`
	VcpuNum          int32  `json:"vcpu_num,omitempty"`
	RamBytes         string `json:"ram_bytes,omitempty"`
	StorageSizeGib   int32  `json:"storage_size_gib,omitempty"`
	Status           string `json:"status,omitempty"`
}

func (tiflash *TiFlashNodeMap) String() string {
	if tiflash == nil {
		return ""
	}
	return fmt.Sprintf("{node_name:%s,availability_zone:%s,node_size:%s,vcpu_num:%d,ram_bytes:%s,storage_size_gib:%d,status:%s}", tiflash.NodeName, tiflash.AvailabilityZone, tiflash.NodeSize, tiflash.VcpuNum, tiflash.RamBytes, tiflash.StorageSizeGib, tiflash.Status)
}

type TiFlashNodeMap struct {
	NodeName         string `json:"node_name,omitempty"`
	AvailabilityZone string `json:"availability_zone,omitempty"`
	NodeSize         string `json:"node_size,omitempty"`
	VcpuNum          int32  `json:"vcpu_num,omitempty"`
	RamBytes         string `json:"ram_bytes,omitempty"`
	StorageSizeGib   int32  `json:"storage_size_gib,omitempty"`
	Status           string `json:"status,omitempty"`
}
