package infrainfo

import (
	"strings"

	dedicatedv1 "github.com/tidbcloud/infra-provider/api/tidbcloud/regional-server/v1"
	"k8s.io/utils/ptr"

	entity "github.com/tidbcloud/devops/entity/k8supgrade"
)

const (
	dedicatedStr = "dedicated"
)

func is3LayerNamespace(ns string) bool {
	return strings.Contains(ns, dedicatedStr)
}

func pbSteps2Entity(steps []*dedicatedv1.UpgradeStep) []*entity.UpgradeStep {
	s := make([]*entity.UpgradeStep, 0, len(steps))
	for _, step := range steps {
		s = append(s, &entity.UpgradeStep{
			Target:    step.Target,
			Version:   step.Version,
			ClusterId: step.ClusterId,
			Options:   step.Options,
		})
	}
	return s
}

func pbUO2Entity(uo *dedicatedv1.UpgradeOperation, ns string) *entity.UpgradeOperation {
	var status entity.UpgradeOperationStatus
	if uo.Status != nil {
		status.Phase, status.Reason = uo.Status.Phase, uo.Status.Reason
		if uo.Status.BeginTime != nil {
			status.BeginTime = ptr.To(uo.Status.BeginTime.AsTime())
		}
		if uo.Status.EndTime != nil {
			status.EndTime = ptr.To(uo.Status.EndTime.AsTime())
		}
	}

	return &entity.UpgradeOperation{
		Name:                  uo.Name,
		Namespace:             ns,
		AppboxName:            uo.AppboxName,
		Schedule:              uo.Schedule,
		Duration:              uo.Duration,
		TTL:                   uo.Ttl,
		MaintenancePolicyMode: uo.MaintenancePolicyMode,
		Annotations:           cloneStringMap(uo.Annotations),
		Steps:                 pbSteps2Entity(uo.Steps),
		Status:                &status,
	}
}

func entity2PBUO(uo *entity.UpgradeOperation) *dedicatedv1.UpgradeOperation {
	return &dedicatedv1.UpgradeOperation{
		Name:                  uo.Name,
		AppboxName:            uo.AppboxName,
		Schedule:              uo.Schedule,
		Duration:              uo.Duration,
		Ttl:                   uo.TTL,
		MaintenancePolicyMode: uo.MaintenancePolicyMode,
		Annotations:           cloneStringMap(uo.Annotations),
		Steps:                 entity2pbSteps(uo.Steps),
	}
}

func cloneStringMap(in map[string]string) map[string]string {
	if len(in) == 0 {
		return nil
	}
	out := make(map[string]string, len(in))
	for k, v := range in {
		out[k] = v
	}
	return out
}

func entity2pbSteps(steps []*entity.UpgradeStep) []*dedicatedv1.UpgradeStep {
	s := make([]*dedicatedv1.UpgradeStep, 0, len(steps))
	for _, step := range steps {
		s = append(s, &dedicatedv1.UpgradeStep{
			Target:    step.Target,
			Version:   step.Version,
			ClusterId: step.ClusterId,
			Options:   step.Options,
		})
	}
	return s
}
