package cvt

import (
	"strconv"
	"strings"

	ccproto "github.com/tidbcloud/config-center/proto/config_center"
	dataflowng "github.com/tidbcloud/dataflow-service-ng/idl/pbgen/proto/consoleapi"
	"github.com/tidbcloud/dataflow-service/idl/pbgen/proto/dataflow"
	ccapi "github.com/tidbcloud/devops/api/cloudconfig"
)

func (c fromDataflow) Changefeed(connector *dataflow.Connector) *ccapi.InternalChangefeed {
	if connector == nil {
		return nil
	}
	createdAt := int64(0)
	if connector.CreatedAt != nil {
		createdAt = connector.CreatedAt.AsTime().Unix()
	}

	return &ccapi.InternalChangefeed{
		DisplayId:      strconv.FormatUint(connector.GetConnectorId(), 10),
		ClusterType:    ccproto.ClusterType_name[int32(ccproto.ClusterType_CHANGEFEED)],
		DisplayName:    connector.GetName(),
		DownstreamType: strings.ToLower(connector.GetConnectorType().String()),
		Status:         connectorStatus(connector.GetStatus()),
		CreatedAt:      createdAt,
	}
}

func (c fromDataflowNg) Changefeed(changefeed *dataflowng.Changefeed) *ccapi.InternalChangefeed {
	if changefeed == nil {
		return nil
	}
	createdAt := int64(0)
	if changefeed.CreatedAt != nil {
		createdAt = changefeed.CreatedAt.AsTime().Unix()
	}

	return &ccapi.InternalChangefeed{
		DisplayId:      strconv.FormatUint(changefeed.GetChangefeedId(), 10),
		ClusterType:    ccproto.ClusterType_name[int32(ccproto.ClusterType_CHANGEFEED_NG)],
		DisplayName:    changefeed.GetName(),
		DownstreamType: strings.ToLower(changefeed.GetChangefeedType().String()),
		Status:         ngChangefeedStatus(changefeed.GetStatus()),
		CreatedAt:      createdAt,
	}
}

func (c fromDataflow) EnrichChangefeed(
	changefeed *ccapi.InternalChangefeed,
	internal *dataflow.InternalChangefeed,
) {
	if changefeed == nil || internal == nil {
		return
	}
	if internal.GetId() != 0 {
		changefeed.Id = strconv.FormatUint(internal.GetId(), 10)
	}
	changefeed.TicdcCluster = c.TiCDCCluster(internal.GetTicdcCluster())
}

func (c fromDataflowNg) EnrichChangefeed(
	changefeed *ccapi.InternalChangefeed,
	internal *dataflowng.InternalChangefeed,
) {
	if changefeed == nil || internal == nil {
		return
	}
	if internal.GetId() != 0 {
		changefeed.Id = strconv.FormatUint(internal.GetId(), 10)
	}
	changefeed.TicdcCluster = c.TiCDCCluster(internal.GetTicdcCluster())
}

func (c fromDataflow) TiCDCCluster(cluster *dataflow.InternalTiCDCCluster) *ccapi.InternalTiCDCCluster {
	if cluster == nil {
		return nil
	}
	createdAt := int64(0)
	if cluster.CreatedAt != nil {
		createdAt = cluster.CreatedAt.AsTime().Unix()
	}

	return &ccapi.InternalTiCDCCluster{
		Id:                strconv.FormatUint(cluster.Id, 10),
		Name:              cluster.Name,
		ClusterType:       ccproto.ClusterType_name[int32(ccproto.ClusterType_TICDC)],
		TidbClusterId:     strconv.FormatUint(cluster.TidbClusterId, 10),
		Version:           cluster.Version,
		Region:            cluster.Region,
		ProviderType:      cluster.ProviderType,
		SpecificationCode: cluster.SpecificationCode,
		Status:            cluster.Status,
		CreatedAt:         createdAt,
		DeployType:        cluster.DeployType,
		ControlPlaneArch:  cluster.ControlplaneArch,
		OperatorVersion:   cluster.OperatorVersion,
	}
}

func (c fromDataflowNg) TiCDCCluster(cluster *dataflowng.InternalTiCDCCluster) *ccapi.InternalTiCDCCluster {
	if cluster == nil {
		return nil
	}
	createdAt := int64(0)
	if cluster.CreatedAt != nil {
		createdAt = cluster.CreatedAt.AsTime().Unix()
	}

	return &ccapi.InternalTiCDCCluster{
		Id:                strconv.FormatUint(cluster.Id, 10),
		Name:              cluster.Name,
		ClusterType:       ccproto.ClusterType_name[int32(ccproto.ClusterType_TICDC_NG)],
		TidbClusterId:     cluster.SharedPoolId,
		Version:           cluster.Version,
		Region:            cluster.Region,
		ProviderType:      cluster.ProviderType,
		SpecificationCode: cluster.SpecificationCode,
		Status:            cluster.Status,
		CreatedAt:         createdAt,
	}
}

func connectorStatus(status dataflow.Connector_Status) string {
	switch status {
	case dataflow.Connector_RUNNING:
		return "normal"
	case dataflow.Connector_WARNING:
		return "warning"
	case dataflow.Connector_ERROR:
		return "error"
	case dataflow.Connector_PAUSING:
		return "stopping"
	case dataflow.Connector_PAUSED:
		return "stopped"
	case dataflow.Connector_RESUMING:
		return "starting"
	default:
		return strings.ToLower(status.String())
	}
}

func ngChangefeedStatus(status dataflowng.Changefeed_Status) string {
	switch status {
	case dataflowng.Changefeed_RUNNING:
		return "normal"
	case dataflowng.Changefeed_WARNING:
		return "warning"
	case dataflowng.Changefeed_ERROR:
		return "error"
	case dataflowng.Changefeed_PAUSING:
		return "stopping"
	case dataflowng.Changefeed_PAUSED:
		return "stopped"
	case dataflowng.Changefeed_RESUMING:
		return "starting"
	default:
		return strings.ToLower(status.String())
	}
}
