package domain

import (
	"github.com/tidbcloud/dataflow-service-ng/app/repo/entity"
	"github.com/tidbcloud/dataflow-service-ng/app/utils"
	"google.golang.org/protobuf/types/known/structpb"
	corev1 "k8s.io/api/core/v1"
)

type Taint struct {
	Effect TaintEffectType
	Key    string
	Value  string
}

type TaintEffectType string

const (
	TaintEffectNoSchedule       TaintEffectType = "NoSchedule"
	TaintEffectPreferNoSchedule TaintEffectType = "PreferNoSchedule"
	TaintEffectNoExecute        TaintEffectType = "NoExecute"
)

func ConvertTaintEffectToK8s(effectType TaintEffectType) corev1.TaintEffect {
	switch effectType {
	case TaintEffectNoSchedule:
		return corev1.TaintEffectNoSchedule
	case TaintEffectPreferNoSchedule:
		return corev1.TaintEffectPreferNoSchedule
	case TaintEffectNoExecute:
		return corev1.TaintEffectNoExecute
	default:
		return corev1.TaintEffectNoSchedule
	}
}

type CreateTiCDCClusterReq struct {
	TenantID      uint64
	SharedPoolID  string
	Region        string
	Name          string
	CloudProvider entity.CloudProviderType

	SpecificationCode string
	Version           string
}

type CreateTiCDCClusterResp struct {
	ID         uint64
	WorkflowID string
}

type QueryTiCDCClusterReq struct {
	ID   uint64
	Name string
}

type QueryTiCDCClusterResp struct {
	TiCDCClusterEntity *entity.TiCDCCluster
}

type DeleteTiCDCClusterReq struct {
	ID uint64
}

type DeleteTiCDCClusterResp struct {
	WorkflowID string
}

type ScaleTiCDCClusterReq struct {
	ID uint64

	SpecificationCode string
}

type ScaleTiCDCClusterResp struct {
	WorkflowID string
}

type ApplyTiCDCClusterConfigReq struct {
	TiCDCClusterID uint64
}

type ListTiCDCClustersReq struct {
	SharedPoolID string
}

type ListTiCDCClustersResp struct {
	Items []entity.TiCDCCluster
}

type RestartTiCDCClusterReq struct {
	TiCDCClusterID uint64
}

type GetTiCDCClusterRoleReq struct {
	SharedPoolID  string
	TiDBClusterID uint64
	Region        string
	CloudProvider string
}

type GetTiCDCClusterRoleResp struct {
	CloudIAMIdentity string
	CloudAccountID   string
	AWSExternalID    string
}

type QuerySpecificationReq struct {
	Code string
}

type QuerySpecificationResp struct {
	Specification *TiCDCClusterSpecification
}

type ListSpecificationsReq struct{}

type ListSpecificationsResp struct {
	Specifications []*TiCDCClusterSpecification
}

type ConvertSpecToResourcesReq struct {
	TiCDCCluster *entity.TiCDCCluster

	SpecificationCode    string
	AWSCloudResourceInfo *AWSCloudResourceInfo
}

type AWSCloudResourceInfo struct {
	CloudAccountID string
	Region         string
	AZSubnetIDMap  map[string]string
	NodeRoleARN    string
	EKSClusterName string
}

type ConvertSpecToResourcesResp struct {
	K8SNodeLabels map[string]string
	K8SNodeTaints []Taint
}

type CreateChangefeedReq struct {
	TiCDCClusterID     uint64
	KernelChangefeedID string

	DownStreamType  entity.TiCDCChangefeedDownStreamType
	Config          *TiCDCChangefeedConfig
	BizChangefeedID uint64
	TiDBClusterID   uint64
}

type CreateChangefeedResp struct {
	TiCDCClusterID uint64
	ChangefeedID   uint64
}

type DeleteChangefeedReq struct {
	ChangefeedID uint64
}

type DeleteChangefeedResp struct{}

type MarkChangefeedDeletedReq struct {
	ChangefeedID uint64
}

type MarkChangefeedDeletedResp struct{}

type ListChangefeedsReq struct {
	Filter *ListChangefeedFilter
	Pager  *Pager
}

type ListChangefeedFilter struct {
	TiCDCClusterIDs     []uint64
	KernelChangefeedIDs []uint64
	Deleted             bool
	BizChangefeedIDs    []uint64
}

type ListChangefeedsResp struct {
	Items []ListChangefeedItem
	Total int64
}

type ListChangefeedItem struct {
	ChangefeedEntity entity.TiCDCChangefeed
}

type PauseChangefeedReq struct {
	ChangefeedID uint64
}

type PauseChangefeedResp struct{}

type ResumeChangefeedReq struct {
	ChangefeedID uint64
}

type ResumeChangefeedResp struct{}

type ModifyChangefeedConfigReq struct {
	ChangefeedID uint64

	Config *TiCDCChangefeedConfig
}

type ModifyChangefeedConfigResp struct{}

type QueryChangefeedReq struct {
	Filter *ListChangefeedFilter
}

type QueryChangefeedResp struct {
	ChangefeedEntity entity.TiCDCChangefeed
	Config           *TiCDCChangefeedConfig
}

type TiCDCChangefeedConfig struct {
	URIConfig TiCDCChangefeedURIConfig
	Config    *TiCDCChangefeedConfigData
}

type MeterChangefeedTrafficReq struct {
	ChangefeedId       uint64
	ChangefeedKernelId string
	PrimaryCluster     *utils.Cluster
	InfoMap            entity.ChangefeedTrafficExtension
}

type MeterChangefeedTrafficResp struct {
	MeterRecord *entity.KernelChangefeedTrafficRecord
}

type GetChangefeedDetailReq struct {
	ChangefeedID entity.ID
}

type GetChangefeedDetailResp struct {
	Changefeed *structpb.Struct
}

type GetChangefeedClusterReq struct {
	ChangefeedID entity.ID
}

type GetChangefeedClusterResp struct {
	TiCDCCluster *structpb.Struct
}

type TiCDCClusterSpecification struct {
	Code     string
	CpuNum   uint32
	Replicas uint32
	RPSLimit uint32
	RCUNum   uint32
}

func (s *TiCDCClusterSpecification) GetRCUNumber() uint32 {
	if s.RCUNum != 0 {
		return s.RCUNum
	}
	return s.CpuNum * s.Replicas
}
