package cluster

import (
	"context"

	"github.com/tidbcloud/chaos-svc/idl/pbgen/proto/chaos"
	"github.com/tidbcloud/chaos-svc/pkg/domain/facade"
	cloudv1 "github.com/tidbcloud/infra-api/api/v1"
	"github.com/tidbcloud/pkgv2/bizerr"
)

type GetTiDBClusterSvc struct {
	infraFacade facade.Infra
}

func NewGetTiDBClusterSvc(infraFacade facade.Infra) *GetTiDBClusterSvc {
	return &GetTiDBClusterSvc{
		infraFacade,
	}
}

func (svc *GetTiDBClusterSvc) Execute(ctx context.Context, req *chaos.GetTiDBComponentTopologyRequest) (*chaos.TiDBComponentTopology, bizerr.BizError) {
	tidbCluster, err := svc.infraFacade.GetTiDBClusterCloudObj(ctx, req.ProjectId, req.ClusterId)
	if err != nil {
		return nil, err
	}
	return buildTiDBComponentTopology(tidbCluster)
}

func buildTiDBComponentTopology(tidb *cloudv1.Cluster) (*chaos.TiDBComponentTopology, bizerr.BizError) {
	if tidb.Status.DB == nil {
		return nil, bizerr.New(bizerr.ErrCodeRecordNotFound, "tidb cluster status is empty")
	}

	topology := &chaos.TiDBComponentTopology{}
	if tidb.Status.DB.PD != nil {
		for _, pd := range tidb.Status.DB.PD.Members {
			topology.Pd = append(topology.Pd, &chaos.ComponentPodInfo{
				Name: pd.Name,
			})
		}
	}

	if tidb.Status.DB.TiDB != nil {
		for _, tidb := range tidb.Status.DB.TiDB.Members {
			topology.Tidb = append(topology.Tidb, &chaos.ComponentPodInfo{
				Name: tidb.Name,
			})
		}
	}

	if tidb.Status.DB.TiKV != nil {
		for _, tikv := range tidb.Status.DB.TiKV.Members {
			topology.Tikv = append(topology.Tikv, &chaos.ComponentPodInfo{
				Name: tikv.Name,
			})
		}
	}

	if tidb.Status.DB.TiFlash != nil {
		for _, tiflash := range tidb.Status.DB.TiFlash.Members {
			topology.Tiflash = append(topology.Tiflash, &chaos.ComponentPodInfo{
				Name: tiflash.Name,
			})
		}
	}

	return topology, nil
}
