package central

type TenantUser struct {
	ID        uint64   `json:"id,string"`
	OrgID     uint64   `json:"org_id,string"`
	Email     string   `json:"email"`
	FirstName string   `json:"first_name"`
	LastName  string   `json:"last_name"`
	Status    string   `json:"status"`
	Roles     []string `json:"roles"`
	Role      string   `json:"role"`
}

type NodeProfileCompute struct {
	CpuNum   int `json:"cpu"`
	MemoryMi int `json:"memory_mi"`
}

type NodeProfileOfComponent struct {
	Compute       NodeProfileCompute `json:"compute"`
	StorageGi     int                `json:"storage_gi"`
	NodeProfileID uint64             `json:"node_profile_id,string"`
	Name          string             `json:"name"`
}

type TenantComponent struct {
	Replicas    uint32                 `json:"replicas"`
	NodeProfile NodeProfileOfComponent `json:"node_profile"` // Deprecated: this filed is not used by config-service.
	MachineType string                 `json:"machineType"`
}

type TenantComponents struct {
	PD      TenantComponent `json:"pd"`
	TiKV    TenantComponent `json:"tikv"`
	TiProxy TenantComponent `json:"tiproxy"`
	TiDB    TenantComponent `json:"tidb"`
	TiFlash TenantComponent `json:"tiflash"`
}

type TenantCluster struct {
	ID               int64            `json:"id,string"`
	Name             string           `json:"name"`
	Provider         string           `json:"provider"`
	Region           string           `json:"region"`
	Profile          string           `json:"profile"`
	Version          string           `json:"version"`
	CreateTime       uint64           `json:"create_time"`
	TenantComponents TenantComponents `json:"tenant_components"`
	Status           string           `json:"status"`
	ProjectID        int64            `json:"project_id,string"`
	ProjectName      string           `json:"project_name"`
	IsDevTier        bool             `json:"is_dev_tier"`
}

// AliveCluster is similar with TenantCluster but remove some deprecated fields.
type AliveCluster struct {
	ID               int64            `json:"id,string"`
	Name             string           `json:"name"`
	Provider         string           `json:"provider"`
	Region           string           `json:"region"`
	Version          string           `json:"version"`
	CreateTime       uint64           `json:"create_time"`
	TenantComponents TenantComponents `json:"tenant_components"`
	Status           string           `json:"status"`
	TenantID         int64            `json:"tenant_id,string"`
	ProjectID        int64            `json:"project_id,string"`
}

func (ac *AliveCluster) TenantCluster() *TenantCluster {
	return &TenantCluster{
		ID:               ac.ID,
		Name:             ac.Name,
		Region:           ac.Region,
		Version:          ac.Version,
		CreateTime:       ac.CreateTime,
		TenantComponents: ac.TenantComponents,
		Status:           ac.Status,
		ProjectID:        ac.ProjectID,
		Provider:         ac.Provider,
	}
}

type Tenant struct {
	ID                        uint64 `json:"id,string"`
	Name                      string `json:"name"`
	Alias                     string `json:"alias"`
	Timezone                  int32  `json:"timezone"`
	Email                     string `json:"email"`
	Status                    string `json:"status"`
	Plan                      string `json:"plan"`
	Discount                  int64  `json:"discount"`
	DiscountDescription       string `json:"discount_description"`
	Country                   string `json:"country"`
	HasDiscount               bool   `json:"has_discount"`
	CreatedAt                 int64  `json:"created_at"`
	Kind                      string `json:"kind"`
	AccountManager            string `json:"account_manager"`
	ThirdPartyAccountProvider string `json:"third_party_account_provider"`
	ThirdPartyAccountCode     string `json:"third_party_account_code"`
}

type TenantFilter struct {
	ID     *uint64  `form:"id" json:"id"`
	Plan   []string `form:"plan" json:"plan" binding:"dive,oneof=new_user free_trial poc on_demand"`
	Kind   []string `form:"kind" json:"kind" binding:"dive,oneof=internal external"`
	Name   *string  `form:"name" json:"name"`
	Alias  *string  `form:"alias" json:"alias"`
	Status []string `form:"status" json:"status" binding:"dive,oneof=pending active inactive deleted cleared"`
}

type ListTenant struct {
	TenantFilter
	SortBy  string `form:"sort_by" json:"sort_by" binding:"omitempty,oneof=timezone created_at"` // options: timezone, created_at
	Order   string `form:"order" json:"order"`                                                   // options: asc or desc
	NoLimit bool   `form:"no-limit,default=false" json:"no_limit"`
	Brief   bool   `form:"brief" json:"brief"`
}

type ListTenantUsersResp struct {
	Total int64        `json:"total"`
	Items []TenantUser `json:"items"`
}

type ListTenantClustersResp struct {
	Total int64           `json:"total"`
	Items []TenantCluster `json:"items"`
}

type ListAliveClustersResp struct {
	Items []AliveCluster `json:"items"`
}

type CentralUserFilter struct {
	Email *string `form:"email" json:"email"`
}

type ListCentralUser struct {
	CentralUserFilter
}

type ListTenantResp struct {
	Total int64    `json:"total"`
	Items []Tenant `json:"items"`
}

type ListTenantClusterLifeCycleResp struct {
	Total int64                    `json:"total"`
	Items []TenantClusterLifecycle `json:"items"`
}

type TenantClusterLifecycle struct {
	Id        uint64 `json:"id,string"`
	ProjectID uint64 `json:"project_id,string"`
	CreatedAt int64  `json:"created_at"`
	DeletedAt int64  `json:"deleted_at"`
}

type ComponentScale struct {
	ComponentType string `json:"component_type" binding:"required,oneof=COMPONENT_TYPE_TIDB COMPONENT_TYPE_TIKV COMPONENT_TYPE_TIFLASH"`
	NodeProfileId uint64 `json:"node_profile_id,string" binding:"required"`
	Replicas      int32  `json:"replicas" binding:"required,gte=0"`
	StorageSizeGi int64  `json:"storage_size_gi" binding:"gte=0"`
}

type ScaleComponentReq struct {
	Components []ComponentScale `json:"components" binding:"required"`
}

type PatchTenantReq struct {
	Kind           *string `json:"kind" binding:"omitempty,oneof=internal external"`
	Alias          *string `json:"alias"`
	AccountManager *string `json:"account_manager" binding:"omitempty,email,endswith=@pingcap.com"` // the email address of account manager, must end with @pingcap.com
}
