package cluster

import (
	"context"

	globaldedicatedv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/dedicated/v1"
	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/entity"
	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/repository/cluster"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

func (s *server) CreateClusterSnapshot(
	ctx context.Context,
	request *globaldedicatedv1.CreateClusterSnapshotRequest,
) (*globaldedicatedv1.CreateClusterSnapshotResponse, error) {
	resp := &globaldedicatedv1.CreateClusterSnapshotResponse{}

	snapshotID, err := s.createClusterSnapshotSvc.Execute(ctx, request.GetClusterId())
	if err != nil {
		return resp, bizerr.WrapError(err, "create cluster snapshot")
	}

	resp.SnapshotId = snapshotID

	return resp, nil
}

func (s *server) ListClusterSnapshots(
	ctx context.Context,
	request *globaldedicatedv1.ListClusterSnapshotsRequest,
) (*globaldedicatedv1.ListClusterSnapshotsResponse, error) {
	resp := &globaldedicatedv1.ListClusterSnapshotsResponse{}

	snapshots, err := s.clusterSnapshotRepo.Query(
		ctx,
		clusterSnapshotFilterToRepo(request.Filter),
		request.Pager,
		request.Sorters,
	)
	if err != nil {
		return resp, err
	}

	out := make([]*globaldedicatedv1.ClusterSnapshot, 0, len(snapshots))
	for _, snapshot := range snapshots {
		out = append(out, clusterSnapshotEnToPb(snapshot))
	}

	resp.Snapshots = out

	return resp, nil
}

func clusterSnapshotFilterToRepo(
	filter *globaldedicatedv1.ListClusterSnapshotsRequest_ClusterSnapshotFilter,
) *cluster.ComponentSnapshotFilter {
	out := cluster.ComponentSnapshotFilter{
		SnapshotsIDs: filter.SnapshotIds,
		TenantIDs:    filter.TenantIds,
		ProjectIDs:   filter.ProjectIds,
		ClusterIDs:   filter.ClusterIds,
	}
	return &out
}

func clusterSnapshotEnToPb(snapshot *entity.ClusterSnapshot) *globaldedicatedv1.ClusterSnapshot {
	out := &globaldedicatedv1.ClusterSnapshot{
		Id:                snapshot.GetId(),
		TenantId:          snapshot.GetTenantId(),
		ProjectId:         snapshot.GetProjectId(),
		CloudProviderName: snapshot.Cluster.CloudProviderId.String(),
	}

	out.Components = append(out.Components, snapshot.Components...)

	return out
}
